summaryrefslogtreecommitdiff
path: root/lib/lufa/LUFA/Drivers/Peripheral/AVR8
diff options
context:
space:
mode:
authorJack Humbert <jack.humb@gmail.com>2017-07-07 11:55:23 -0400
committerJack Humbert <jack.humb@gmail.com>2017-07-07 11:55:23 -0400
commit8655d4f4948b2deef7844503c8d690f23ac1a062 (patch)
treeb2c6effc9d6cd5b5b43933a1e53b8bf17e9e82cf /lib/lufa/LUFA/Drivers/Peripheral/AVR8
parent1896c76a2928c96f9ab7947bec2ef8dd37623cff (diff)
parent60b30c036397cb5627fa374bb930794b225daa29 (diff)
Merge commit '60b30c036397cb5627fa374bb930794b225daa29' as 'lib/lufa'
Diffstat (limited to 'lib/lufa/LUFA/Drivers/Peripheral/AVR8')
-rw-r--r--lib/lufa/LUFA/Drivers/Peripheral/AVR8/ADC_AVR8.h446
-rw-r--r--lib/lufa/LUFA/Drivers/Peripheral/AVR8/SPI_AVR8.h258
-rw-r--r--lib/lufa/LUFA/Drivers/Peripheral/AVR8/SerialSPI_AVR8.h208
-rw-r--r--lib/lufa/LUFA/Drivers/Peripheral/AVR8/Serial_AVR8.c121
-rw-r--r--lib/lufa/LUFA/Drivers/Peripheral/AVR8/Serial_AVR8.h271
-rw-r--r--lib/lufa/LUFA/Drivers/Peripheral/AVR8/TWI_AVR8.c209
-rw-r--r--lib/lufa/LUFA/Drivers/Peripheral/AVR8/TWI_AVR8.h305
7 files changed, 1818 insertions, 0 deletions
diff --git a/lib/lufa/LUFA/Drivers/Peripheral/AVR8/ADC_AVR8.h b/lib/lufa/LUFA/Drivers/Peripheral/AVR8/ADC_AVR8.h
new file mode 100644
index 0000000000..a2b7eded3d
--- /dev/null
+++ b/lib/lufa/LUFA/Drivers/Peripheral/AVR8/ADC_AVR8.h
@@ -0,0 +1,446 @@
+/*
+ LUFA Library
+ Copyright (C) Dean Camera, 2017.
+
+ dean [at] fourwalledcubicle [dot] com
+ www.lufa-lib.org
+*/
+
+/*
+ Copyright 2017 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 disclaims 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
+ * \brief ADC Peripheral Driver (AVR8)
+ *
+ * On-chip Analogue-to-Digital converter (ADC) driver for supported U4, U6 and U7 model AVRs that contain an ADC
+ * peripheral internally.
+ *
+ * \note This file should not be included directly. It is automatically included as needed by the ADC driver
+ * dispatch header located in LUFA/Drivers/Peripheral/ADC.h.
+ */
+
+/** \ingroup Group_ADC
+ * \defgroup Group_ADC_AVR8 ADC Peripheral Driver (AVR8)
+ *
+ * \section Sec_ADC_AVR8_ModDescription Module Description
+ * On-chip Analogue-to-Digital converter (ADC) driver for supported U4, U6 and U7 model AVRs that contain an ADC
+ * peripheral internally.
+ *
+ * \note This file should not be included directly. It is automatically included as needed by the ADC driver
+ * dispatch header located in LUFA/Drivers/Peripheral/ADC.h.
+ *
+ * \section Sec_ADC_AVR8_ExampleUsage Example Usage
+ * The following snippet is an example of how this module may be used within a typical
+ * application.
+ *
+ * \code
+ * // Initialize the ADC driver before first use
+ * ADC_Init(ADC_FREE_RUNNING | ADC_PRESCALE_32);
+ *
+ * // Must setup the ADC channel to read beforehand
+ * ADC_SetupChannel(1);
+ *
+ * // Perform a single conversion of the ADC channel 1
+ * ADC_GetChannelReading(ADC_REFERENCE_AVCC | ADC_RIGHT_ADJUSTED | ADC_CHANNEL1);
+ * printf("Conversion Result: %d\r\n", ADC_GetResult());
+ *
+ * // Start reading ADC channel 1 in free running (continuous conversion) mode
+ * ADC_StartReading(ADC_REFERENCE_AVCC | ADC_RIGHT_ADJUSTED | ADC_CHANNEL1);
+ * for (;;)
+ * {
+ * while (!(ADC_IsReadingComplete())) {};
+ * printf("Conversion Result: %d\r\n", ADC_GetResult());
+ * }
+ * \endcode
+ *
+ * @{
+ */
+
+#ifndef __ADC_AVR8_H__
+#define __ADC_AVR8_H__
+
+ /* Includes: */
+ #include "../../../Common/Common.h"
+
+ /* Enable C linkage for C++ Compilers: */
+ #if defined(__cplusplus)
+ extern "C" {
+ #endif
+
+ /* Preprocessor Checks: */
+ #if !defined(__INCLUDE_FROM_ADC_H)
+ #error Do not include this file directly. Include LUFA/Drivers/Peripheral/ADC.h instead.
+ #endif
+
+ #if !(defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB646__) || \
+ defined(__AVR_AT90USB1287__) || defined(__AVR_AT90USB647__) || \
+ defined(__AVR_ATmega16U4__) || defined(__AVR_ATmega32U4__))
+ #error The ADC peripheral driver is not currently available for your selected microcontroller model.
+ #endif
+
+ /* Public Interface - May be used in end-application: */
+ /* Macros: */
+ /** \name ADC Reference Configuration Masks */
+ //@{
+ /** Reference mask, for using the voltage present at the AVR's AREF pin for the ADC reference. */
+ #define ADC_REFERENCE_AREF 0
+
+ /** Reference mask, for using the voltage present at the AVR's AVCC pin for the ADC reference. */
+ #define ADC_REFERENCE_AVCC (1 << REFS0)
+
+ /** Reference mask, for using the internally generated 2.56V reference voltage as the ADC reference. */
+ #define ADC_REFERENCE_INT2560MV ((1 << REFS1) | (1 << REFS0))
+ //@}
+
+ /** \name ADC Result Adjustment Configuration Masks */
+ //@{
+ /** Left-adjusts the 10-bit ADC result, so that the upper 8 bits of the value returned by the
+ * \ref ADC_GetResult() macro contain the 8 most significant bits of the result.
+ */
+ #define ADC_LEFT_ADJUSTED (1 << ADLAR)
+
+ /** Right-adjusts the 10-bit ADC result, so that the lower 8 bits of the value returned by the
+ * \ref ADC_GetResult() macro contain the 8 least significant bits of the result.
+ */
+ #define ADC_RIGHT_ADJUSTED (0 << ADLAR)
+ //@}
+
+ /** \name ADC Mode Configuration Masks */
+ //@{
+ /** Sets the ADC mode to free running, so that conversions take place continuously as fast as the ADC
+ * is capable of at the given input clock speed.
+ */
+ #define ADC_FREE_RUNNING (1 << ADATE)
+
+ /** Sets the ADC mode to single conversion, so that only a single conversion will take place before
+ * the ADC returns to idle.
+ */
+ #define ADC_SINGLE_CONVERSION (0 << ADATE)
+ //@}
+
+ /** \name ADC Prescaler Configuration Masks */
+ //@{
+ /** Sets the ADC input clock to prescale by a factor of 2 the AVR's system clock. */
+ #define ADC_PRESCALE_2 (1 << ADPS0)
+
+ /** Sets the ADC input clock to prescale by a factor of 4 the AVR's system clock. */
+ #define ADC_PRESCALE_4 (1 << ADPS1)
+
+ /** Sets the ADC input clock to prescale by a factor of 8 the AVR's system clock. */
+ #define ADC_PRESCALE_8 ((1 << ADPS0) | (1 << ADPS1))
+
+ /** Sets the ADC input clock to prescale by a factor of 16 the AVR's system clock. */
+ #define ADC_PRESCALE_16 (1 << ADPS2)
+
+ /** Sets the ADC input clock to prescale by a factor of 32 the AVR's system clock. */
+ #define ADC_PRESCALE_32 ((1 << ADPS2) | (1 << ADPS0))
+
+ /** Sets the ADC input clock to prescale by a factor of 64 the AVR's system clock. */
+ #define ADC_PRESCALE_64 ((1 << ADPS2) | (1 << ADPS1))
+
+ /** Sets the ADC input clock to prescale by a factor of 128 the AVR's system clock. */
+ #define ADC_PRESCALE_128 ((1 << ADPS2) | (1 << ADPS1) | (1 << ADPS0))
+ //@}
+
+ /** \name ADC MUX Masks */
+ //@{
+ /** MUX mask define for the ADC0 channel of the ADC. See \ref ADC_StartReading() and \ref ADC_GetChannelReading(). */
+ #define ADC_CHANNEL0 (0x00 << MUX0)
+
+ /** MUX mask define for the ADC1 channel of the ADC. See \ref ADC_StartReading() and \ref ADC_GetChannelReading(). */
+ #define ADC_CHANNEL1 (0x01 << MUX0)
+
+ #if (!(defined(__AVR_ATmega16U4__) || defined(__AVR_ATmega32U4__)) || defined(__DOXYGEN__))
+ /** MUX mask define for the ADC2 channel of the ADC. See \ref ADC_StartReading() and \ref ADC_GetChannelReading().
+ *
+ * \note Not available on all AVR models.
+ */
+ #define ADC_CHANNEL2 (0x02 << MUX0)
+
+ /** MUX mask define for the ADC3 channel of the ADC. See \ref ADC_StartReading() and \ref ADC_GetChannelReading().
+ *
+ * \note Not available on all AVR models.
+ */
+ #define ADC_CHANNEL3 (0x03 << MUX0)
+ #endif
+
+ /** MUX mask define for the ADC4 channel of the ADC. See \ref ADC_StartReading() and \ref ADC_GetChannelReading(). */
+ #define ADC_CHANNEL4 (0x04 << MUX0)
+
+ /** MUX mask define for the ADC5 channel of the ADC. See \ref ADC_StartReading() and \ref ADC_GetChannelReading(). */
+ #define ADC_CHANNEL5 (0x05 << MUX0)
+
+ /** MUX mask define for the ADC6 channel of the ADC. See \ref ADC_StartReading() and \ref ADC_GetChannelReading(). */
+ #define ADC_CHANNEL6 (0x06 << MUX0)
+
+ /** MUX mask define for the ADC7 channel of the ADC. See \ref ADC_StartReading and \ref ADC_GetChannelReading. */
+ #define ADC_CHANNEL7 (0x07 << MUX0)
+
+ #if (defined(__AVR_ATmega16U4__) || defined(__AVR_ATmega32U4__) || defined(__DOXYGEN__))
+ /** MUX mask define for the ADC8 channel of the ADC. See \ref ADC_StartReading() and \ref ADC_GetChannelReading().
+ *
+ * \note Not available on all AVR models.
+ */
+ #define ADC_CHANNEL8 ((1 << 8) | (0x00 << MUX0))
+
+ /** MUX mask define for the ADC9 channel of the ADC. See \ref ADC_StartReading() and \ref ADC_GetChannelReading().
+ *
+ * \note Not available on all AVR models.
+ */
+ #define ADC_CHANNEL9 ((1 << 8) | (0x01 << MUX0))
+
+ /** MUX mask define for the ADC10 channel of the ADC. See \ref ADC_StartReading() and \ref ADC_GetChannelReading().
+ *
+ * \note Not available on all AVR models.
+ */
+ #define ADC_CHANNEL10 ((1 << 8) | (0x02 << MUX0))
+
+ /** MUX mask define for the ADC11 channel of the ADC. See \ref ADC_StartReading() and \ref ADC_GetChannelReading().
+ *
+ * \note Not available on all AVR models.
+ */
+ #define ADC_CHANNEL11 ((1 << 8) | (0x03 << MUX0))
+
+ /** MUX mask define for the ADC12 channel of the ADC. See \ref ADC_StartReading() and \ref ADC_GetChannelReading().
+ *
+ * \note Not available on all AVR models.
+ */
+ #define ADC_CHANNEL12 ((1 << 8) | (0x04 << MUX0))
+
+ /** MUX mask define for the ADC13 channel of the ADC. See \ref ADC_StartReading() and \ref ADC_GetChannelReading().
+ *
+ * \note Not available on all AVR models.
+ */
+ #define ADC_CHANNEL13 ((1 << 8) | (0x05 << MUX0))
+
+ /** MUX mask define for the internal temperature sensor channel of the ADC. See \ref ADC_StartReading() and
+ * \ref ADC_GetChannelReading().
+ *
+ * \note Not available on all AVR models.
+ */
+ #define ADC_INT_TEMP_SENS ((1 << 8) | (0x07 << MUX0))
+ #endif
+
+ /** MUX mask define for the internal 1.1V band-gap channel of the ADC. See \ref ADC_StartReading() and \ref ADC_GetChannelReading(). */
+ #define ADC_1100MV_BANDGAP (0x1E << MUX0)
+
+ /** Retrieves the ADC MUX mask for the given ADC channel number.
+ *
+ * \attention This macro will only work correctly on channel numbers that are compile-time
+ * constants defined by the preprocessor.
+ *
+ * \param[in] Channel Index of the ADC channel whose MUX mask is to be retrieved.
+ */
+ #define ADC_GET_CHANNEL_MASK(Channel) CONCAT_EXPANDED(ADC_CHANNEL, Channel)
+ //@}
+
+ /* Inline Functions: */
+ /** Configures the given ADC channel, ready for ADC conversions. This function sets the
+ * associated port pin as an input and disables the digital portion of the I/O to reduce
+ * power consumption.
+ *
+ * \note This must only be called for ADC channels with are connected to a physical port
+ * pin of the AVR, denoted by its special alternative function ADCx.
+ *
+ * \warning The channel number must be specified as an integer, and <b>not</b> a \c ADC_CHANNEL* mask.
+ *
+ * \param[in] ChannelIndex ADC channel number to set up for conversions.
+ */
+ static inline void ADC_SetupChannel(const uint8_t ChannelIndex)
+ {
+ #if (defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB646__) || \
+ defined(__AVR_AT90USB1287__) || defined(__AVR_AT90USB647__))
+ DDRF &= ~(1 << ChannelIndex);
+ DIDR0 |= (1 << ChannelIndex);
+ #elif (defined(__AVR_ATmega16U4__) || defined(__AVR_ATmega32U4__))
+ if (ChannelIndex < 8)
+ {
+ DDRF &= ~(1 << ChannelIndex);
+ DIDR0 |= (1 << ChannelIndex);
+ }
+ else if (ChannelIndex == 8)
+ {
+ DDRD &= ~(1 << 4);
+ DIDR2 |= (1 << 0);
+ }
+ else if (ChannelIndex < 11)
+ {
+ DDRD &= ~(1 << (ChannelIndex - 3));
+ DIDR2 |= (1 << (ChannelIndex - 8));
+ }
+ else
+ {
+ DDRB &= ~(1 << (ChannelIndex - 7));
+ DIDR2 |= (1 << (ChannelIndex - 8));
+ }
+ #endif
+ }
+
+ /** De-configures the given ADC channel, re-enabling digital I/O mode instead of analog. This
+ * function sets the associated port pin as an input and re-enabled the digital portion of
+ * the I/O.
+ *
+ * \note This must only be called for ADC channels with are connected to a physical port
+ * pin of the AVR, denoted by its special alternative function ADCx.
+ *
+ * \warning The channel number must be specified as an integer, and <b>not</b> a \c ADC_CHANNEL* mask.
+ *
+ * \param[in] ChannelIndex ADC channel number to set up for conversions.
+ */
+ static inline void ADC_DisableChannel(const uint8_t ChannelIndex)
+ {
+ #if (defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB646__) || \
+ defined(__AVR_AT90USB1287__) || defined(__AVR_AT90USB647__))
+ DDRF &= ~(1 << ChannelIndex);
+ DIDR0 &= ~(1 << ChannelIndex);
+ #elif (defined(__AVR_ATmega16U4__) || defined(__AVR_ATmega32U4__))
+ if (ChannelIndex < 8)
+ {
+ DDRF &= ~(1 << ChannelIndex);
+ DIDR0 &= ~(1 << ChannelIndex);
+ }
+ else if (ChannelIndex == 8)
+ {
+ DDRD &= ~(1 << 4);
+ DIDR2 &= ~(1 << 0);
+ }
+ else if (ChannelIndex < 11)
+ {
+ DDRD &= ~(1 << (ChannelIndex - 3));
+ DIDR2 &= ~(1 << (ChannelIndex - 8));
+ }
+ else
+ {
+ DDRB &= ~(1 << (ChannelIndex - 7));
+ DIDR2 &= ~(1 << (ChannelIndex - 8));
+ }
+ #endif
+ }
+
+ /** Starts the reading of the given channel, but does not wait until the conversion has completed.
+ * Once executed, the conversion status can be determined via the \ref ADC_IsReadingComplete() macro and
+ * the result read via the \ref ADC_GetResult() macro.
+ *
+ * If the ADC has been initialized in free running mode, calling this function once will begin the repeated
+ * conversions. If the ADC is in single conversion mode (or the channel to convert from is to be changed),
+ * this function must be called each time a conversion is to take place.
+ *
+ * \param[in] MUXMask ADC channel mask, reference mask and adjustment mask.
+ */
+ static inline void ADC_StartReading(const uint16_t MUXMask)
+ {
+ ADMUX = MUXMask;
+
+ #if (defined(__AVR_ATmega16U4__) || defined(__AVR_ATmega32U4__) || defined(__DOXYGEN__))
+ if (MUXMask & (1 << 8))
+ ADCSRB |= (1 << MUX5);
+ else
+ ADCSRB &= ~(1 << MUX5);
+ #endif
+
+ ADCSRA |= (1 << ADSC);
+ }
+
+ /** Indicates if the current ADC conversion is completed, or still in progress.
+ *
+ * \return Boolean \c false if the reading is still taking place, or true if the conversion is
+ * complete and ready to be read out with \ref ADC_GetResult().
+ */
+ static inline bool ADC_IsReadingComplete(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
+ static inline bool ADC_IsReadingComplete(void)
+ {
+ return ((ADCSRA & (1 << ADIF)) ? true : false);
+ }
+
+ /** Retrieves the conversion value of the last completed ADC conversion and clears the reading
+ * completion flag.
+ *
+ * \return The result of the last ADC conversion as an unsigned value.
+ */
+ static inline uint16_t ADC_GetResult(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
+ static inline uint16_t ADC_GetResult(void)
+ {
+ ADCSRA |= (1 << ADIF);
+ return ADC;
+ }
+
+ /** Performs a complete single reading from channel, including a polling spin-loop to wait for the
+ * conversion to complete, and the returning of the converted value.
+ *
+ * \note For free running mode, the automated conversions should be initialized with a single call
+ * to \ref ADC_StartReading() to select the channel and begin the automated conversions, and
+ * the results read directly from the \ref ADC_GetResult() instead to reduce overhead.
+ *
+ * \param[in] MUXMask Mask comprising of an ADC channel mask, reference mask and adjustment mask.
+ *
+ * \return Converted ADC result for the given ADC channel.
+ */
+ static inline uint16_t ADC_GetChannelReading(const uint16_t MUXMask) ATTR_WARN_UNUSED_RESULT;
+ static inline uint16_t ADC_GetChannelReading(const uint16_t MUXMask)
+ {
+ ADC_StartReading(MUXMask);
+
+ while (!(ADC_IsReadingComplete()));
+
+ return ADC_GetResult();
+ }
+
+ /** Initializes the ADC, ready for conversions. This must be called before any other ADC operations.
+ * The "mode" parameter should be a mask comprised of a conversion mode (free running or single) and
+ * prescaler masks.
+ *
+ * \param[in] Mode Mask of ADC prescale and mode settings.
+ */
+ static inline void ADC_Init(const uint8_t Mode) ATTR_ALWAYS_INLINE;
+ static inline void ADC_Init(const uint8_t Mode)
+ {
+ ADCSRA = ((1 << ADEN) | Mode);
+ }
+
+ /** Turns off the ADC. If this is called, any further ADC operations will require a call to
+ * \ref ADC_Init() before the ADC can be used again.
+ */
+ static inline void ADC_Disable(void) ATTR_ALWAYS_INLINE;
+ static inline void ADC_Disable(void)
+ {
+ ADCSRA = 0;
+ }
+
+ /** Indicates if the ADC is currently enabled.
+ *
+ * \return Boolean \c true if the ADC subsystem is currently enabled, \c false otherwise.
+ */
+ static inline bool ADC_GetStatus(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
+ static inline bool ADC_GetStatus(void)
+ {
+ return ((ADCSRA & (1 << ADEN)) ? true : false);
+ }
+
+ /* Disable C linkage for C++ Compilers: */
+ #if defined(__cplusplus)
+ }
+ #endif
+
+#endif
+
+/** @} */
+
diff --git a/lib/lufa/LUFA/Drivers/Peripheral/AVR8/SPI_AVR8.h b/lib/lufa/LUFA/Drivers/Peripheral/AVR8/SPI_AVR8.h
new file mode 100644
index 0000000000..7244f4a954
--- /dev/null
+++ b/lib/lufa/LUFA/Drivers/Peripheral/AVR8/SPI_AVR8.h
@@ -0,0 +1,258 @@
+/*
+ LUFA Library
+ Copyright (C) Dean Camera, 2017.
+
+ dean [at] fourwalledcubicle [dot] com
+ www.lufa-lib.org
+*/
+
+/*
+ Copyright 2017 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 disclaims 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
+ * \brief SPI Peripheral Driver (AVR8)
+ *
+ * On-chip SPI driver for the 8-bit AVR microcontrollers.
+ *
+ * \note This file should not be included directly. It is automatically included as needed by the SPI driver
+ * dispatch header located in LUFA/Drivers/Peripheral/SPI.h.
+ */
+
+/** \ingroup Group_SPI
+ * \defgroup Group_SPI_AVR8 SPI Peripheral Driver (AVR8)
+ *
+ * \section Sec_SPI_AVR8_ModDescription Module Description
+ * Driver for the hardware SPI port available on most 8-bit AVR microcontroller models. This
+ * module provides an easy to use driver for the setup and transfer of data over the
+ * AVR's SPI port.
+ *
+ * \note This file should not be included directly. It is automatically included as needed by the SPI driver
+ * dispatch header located in LUFA/Drivers/Peripheral/SPI.h.
+ *
+ * \section Sec_SPI_AVR8_ExampleUsage Example Usage
+ * The following snippet is an example of how this module may be used within a typical
+ * application.
+ *
+ * \code
+ * // Initialize the SPI driver before first use
+ * SPI_Init(SPI_SPEED_FCPU_DIV_2 | SPI_ORDER_MSB_FIRST | SPI_SCK_LEAD_FALLING |
+ * SPI_SAMPLE_TRAILING | SPI_MODE_MASTER);
+ *
+ * // Send several bytes, ignoring the returned data
+ * SPI_SendByte(0x01);
+ * SPI_SendByte(0x02);
+ * SPI_SendByte(0x03);
+ *
+ * // Receive several bytes, sending a dummy 0x00 byte each time
+ * uint8_t Byte1 = SPI_ReceiveByte();
+ * uint8_t Byte2 = SPI_ReceiveByte();
+ * uint8_t Byte3 = SPI_ReceiveByte();
+ *
+ * // Send a byte, and store the received byte from the same transaction
+ * uint8_t ResponseByte = SPI_TransferByte(0xDC);
+ * \endcode
+ *
+ * @{
+ */
+
+#ifndef __SPI_AVR8_H__
+#define __SPI_AVR8_H__
+
+ /* Includes: */
+ #include "../../../Common/Common.h"
+
+ /* Enable C linkage for C++ Compilers: */
+ #if defined(__cplusplus)
+ extern "C" {
+ #endif
+
+ /* Preprocessor Checks: */
+ #if !defined(__INCLUDE_FROM_SPI_H)
+ #error Do not include this file directly. Include LUFA/Drivers/Peripheral/SPI.h instead.
+ #endif
+
+ /* Private Interface - For use in library only: */
+ #if !defined(__DOXYGEN__)
+ /* Macros: */
+ #define SPI_USE_DOUBLESPEED (1 << SPE)
+ #endif
+
+ /* Public Interface - May be used in end-application: */
+ /* Macros: */
+ /** \name SPI Prescaler Configuration Masks */
+ //@{
+ /** SPI prescaler mask for \ref SPI_Init(). Divides the system clock by a factor of 2. */
+ #define SPI_SPEED_FCPU_DIV_2 SPI_USE_DOUBLESPEED
+
+ /** SPI prescaler mask for \ref SPI_Init(). Divides the system clock by a factor of 4. */
+ #define SPI_SPEED_FCPU_DIV_4 0
+
+ /** SPI prescaler mask for \ref SPI_Init(). Divides the system clock by a factor of 8. */
+ #define SPI_SPEED_FCPU_DIV_8 (SPI_USE_DOUBLESPEED | (1 << SPR0))
+
+ /** SPI prescaler mask for \ref SPI_Init(). Divides the system clock by a factor of 16. */
+ #define SPI_SPEED_FCPU_DIV_16 (1 << SPR0)
+
+ /** SPI prescaler mask for \ref SPI_Init(). Divides the system clock by a factor of 32. */
+ #define SPI_SPEED_FCPU_DIV_32 (SPI_USE_DOUBLESPEED | (1 << SPR1))
+
+ /** SPI prescaler mask for \ref SPI_Init(). Divides the system clock by a factor of 64. */
+ #define SPI_SPEED_FCPU_DIV_64 (SPI_USE_DOUBLESPEED | (1 << SPR1) | (1 << SPR0))
+
+ /** SPI prescaler mask for \ref SPI_Init(). Divides the system clock by a factor of 128. */
+ #define SPI_SPEED_FCPU_DIV_128 ((1 << SPR1) | (1 << SPR0))
+ //@}
+
+ /** \name SPI SCK Polarity Configuration Masks */
+ //@{
+ /** SPI clock polarity mask for \ref SPI_Init(). Indicates that the SCK should lead on the rising edge. */
+ #define SPI_SCK_LEAD_RISING (0 << CPOL)
+
+ /** SPI clock polarity mask for \ref SPI_Init(). Indicates that the SCK should lead on the falling edge. */
+ #define SPI_SCK_LEAD_FALLING (1 << CPOL)
+ //@}
+
+ /** \name SPI Sample Edge Configuration Masks */
+ //@{
+ /** SPI data sample mode mask for \ref SPI_Init(). Indicates that the data should sampled on the leading edge. */
+ #define SPI_SAMPLE_LEADING (0 << CPHA)
+
+ /** SPI data sample mode mask for \ref SPI_Init(). Indicates that the data should be sampled on the trailing edge. */
+ #define SPI_SAMPLE_TRAILING (1 << CPHA)
+ //@}
+
+ /** \name SPI Data Ordering Configuration Masks */
+ //@{
+ /** SPI data order mask for \ref SPI_Init(). Indicates that data should be shifted out MSB first. */
+ #define SPI_ORDER_MSB_FIRST (0 << DORD)
+
+ /** SPI data order mask for \ref SPI_Init(). Indicates that data should be shifted out LSB first. */
+ #define SPI_ORDER_LSB_FIRST (1 << DORD)
+ //@}
+
+ /** \name SPI Mode Configuration Masks */
+ //@{
+ /** SPI mode mask for \ref SPI_Init(). Indicates that the SPI interface should be initialized into slave mode. */
+ #define SPI_MODE_SLAVE (0 << MSTR)
+
+ /** SPI mode mask for \ref SPI_Init(). Indicates that the SPI interface should be initialized into master mode. */
+ #define SPI_MODE_MASTER (1 << MSTR)
+ //@}
+
+ /* Inline Functions: */
+ /** Initializes the SPI subsystem, ready for transfers. Must be called before calling any other
+ * SPI routines.
+ *
+ * \param[in] SPIOptions SPI Options, a mask consisting of one of each of the \c SPI_SPEED_*,
+ * \c SPI_SCK_*, \c SPI_SAMPLE_*, \c SPI_ORDER_* and \c SPI_MODE_* masks.
+ */
+ static inline void SPI_Init(const uint8_t SPIOptions);
+ static inline void SPI_Init(const uint8_t SPIOptions)
+ {
+ /* Prevent high rise times on PB.0 (/SS) from forcing a change to SPI slave mode */
+ DDRB |= (1 << 0);
+ PORTB |= (1 << 0);
+
+ DDRB |= ((1 << 1) | (1 << 2));
+ DDRB &= ~(1 << 3);
+ PORTB |= (1 << 3);
+
+ if (SPIOptions & SPI_USE_DOUBLESPEED)
+ SPSR |= (1 << SPI2X);
+ else
+ SPSR &= ~(1 << SPI2X);
+
+ /* Switch /SS to input mode after configuration to allow for forced mode changes */
+ DDRB &= ~(1 << 0);
+
+ SPCR = ((1 << SPE) | SPIOptions);
+ }
+
+ /** Turns off the SPI driver, disabling and returning used hardware to their default configuration. */
+ static inline void SPI_Disable(void);
+ static inline void SPI_Disable(void)
+ {
+ DDRB &= ~((1 << 1) | (1 << 2));
+ PORTB &= ~((1 << 0) | (1 << 3));
+
+ SPCR = 0;
+ SPSR = 0;
+ }
+
+ /** Retrieves the currently selected SPI mode, once the SPI interface has been configured.
+ *
+ * \return \ref SPI_MODE_MASTER if the interface is currently in SPI Master mode, \ref SPI_MODE_SLAVE otherwise
+ */
+ static inline uint8_t SPI_GetCurrentMode(void) ATTR_ALWAYS_INLINE;
+ static inline uint8_t SPI_GetCurrentMode(void)
+ {
+ return (SPCR & SPI_MODE_MASTER);
+ }
+
+ /** Sends and receives a byte through the SPI interface, blocking until the transfer is complete.
+ *
+ * \param[in] Byte Byte to send through the SPI interface.
+ *
+ * \return Response byte from the attached SPI device.
+ */
+ static inline uint8_t SPI_TransferByte(const uint8_t Byte) ATTR_ALWAYS_INLINE;
+ static inline uint8_t SPI_TransferByte(const uint8_t Byte)
+ {
+ SPDR = Byte;
+ while (!(SPSR & (1 << SPIF)));
+ return SPDR;
+ }
+
+ /** Sends a byte through the SPI interface, blocking until the transfer is complete. The response
+ * byte sent to from the attached SPI device is ignored.
+ *
+ * \param[in] Byte Byte to send through the SPI interface.
+ */
+ static inline void SPI_SendByte(const uint8_t Byte) ATTR_ALWAYS_INLINE;
+ static inline void SPI_SendByte(const uint8_t Byte)
+ {
+ SPDR = Byte;
+ while (!(SPSR & (1 << SPIF)));
+ }
+
+ /** Sends a dummy byte through the SPI interface, blocking until the transfer is complete. The response
+ * byte from the attached SPI device is returned.
+ *
+ * \return The response byte from the attached SPI device.
+ */
+ static inline uint8_t SPI_ReceiveByte(void) ATTR_ALWAYS_INLINE ATTR_WARN_UNUSED_RESULT;
+ static inline uint8_t SPI_ReceiveByte(void)
+ {
+ SPDR = 0x00;
+ while (!(SPSR & (1 << SPIF)));
+ return SPDR;
+ }
+
+ /* Disable C linkage for C++ Compilers: */
+ #if defined(__cplusplus)
+ }
+ #endif
+
+#endif
+
+/** @} */
+
diff --git a/lib/lufa/LUFA/Drivers/Peripheral/AVR8/SerialSPI_AVR8.h b/lib/lufa/LUFA/Drivers/Peripheral/AVR8/SerialSPI_AVR8.h
new file mode 100644
index 0000000000..052780e733
--- /dev/null
+++ b/lib/lufa/LUFA/Drivers/Peripheral/AVR8/SerialSPI_AVR8.h
@@ -0,0 +1,208 @@
+/*
+ LUFA Library
+ Copyright (C) Dean Camera, 2017.
+
+ dean [at] fourwalledcubicle [dot] com
+ www.lufa-lib.org
+*/
+
+/*
+ Copyright 2017 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 disclaims 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
+ * \brief Master SPI Mode Serial USART Peripheral Driver (XMEGA)
+ *
+ * On-chip Master SPI mode USART driver for the XMEGA AVR microcontrollers.
+ *
+ * \note This file should not be included directly. It is automatically included as needed by the SPI Master
+ * Mode USART driver dispatch header located in LUFA/Drivers/Peripheral/Serial.h.
+ */
+
+/** \ingroup Group_SerialSPI
+ * \defgroup Group_SerialSPI_AVR8 Master SPI Mode Serial USART Peripheral Driver (AVR8)
+ *
+ * \section Sec_SerialSPI_AVR8_ModDescription Module Description
+ * On-chip serial USART driver for the 8-bit AVR8 microcontrollers.
+ *
+ * \note This file should not be included directly. It is automatically included as needed by the SPI Master
+ * driver dispatch header located in LUFA/Drivers/Peripheral/SerialSPI.h.
+ *
+ * \section Sec_SerialSPI_AVR8_ExampleUsage Example Usage
+ * The following snippet is an example of how this module may be used within a typical
+ * application.
+ *
+ * \code
+ * // Initialize the Master SPI mode USART driver before first use, with 1Mbit baud
+ * SerialSPI_Init((USART_SPI_SCK_LEAD_RISING | USART_SPI_SAMPLE_LEADING | USART_SPI_ORDER_MSB_FIRST), 1000000);
+ *
+ * // Send several bytes, ignoring the returned data
+ * SerialSPI_SendByte(0x01);
+ * SerialSPI_SendByte(0x02);
+ * SerialSPI_SendByte(0x03);
+ *
+ * // Receive several bytes, sending a dummy 0x00 byte each time
+ * uint8_t Byte1 = SerialSPI_ReceiveByte();
+ * uint8_t Byte2 = SerialSPI_ReceiveByte();
+ * uint8_t Byte3 = SerialSPI_ReceiveByte();
+ *
+ * // Send a byte, and store the received byte from the same transaction
+ * uint8_t ResponseByte = SerialSPI_TransferByte(0xDC);
+ * \endcode
+ *
+ * @{
+ */
+
+#ifndef __SERIAL_SPI_AVR8_H__
+#define __SERIAL_SPI_AVR8_H__
+
+ /* Includes: */
+ #include "../../../Common/Common.h"
+
+ #include <stdio.h>
+
+ /* Enable C linkage for C++ Compilers: */
+ #if defined(__cplusplus)
+ extern "C" {
+ #endif
+
+ /* Preprocessor Checks: */
+ #if !defined(__INCLUDE_FROM_SERIAL_SPI_H)
+ #error Do not include this file directly. Include LUFA/Drivers/Peripheral/Serial.h instead.
+ #endif
+
+ /* Private Interface - For use in library only: */
+ #if !defined(__DOXYGEN__)
+ #define SERIAL_SPI_UBBRVAL(Baud) ((Baud < (F_CPU / 2)) ? ((F_CPU / (2 * Baud)) - 1) : 0)
+
+ /* Master USART SPI mode flag definitions missing in the AVR8 toolchain */
+ #if !defined(UCPHA1)
+ #define UCPHA1 1
+ #endif
+ #if !defined(UDORD1)
+ #define UDORD1 2
+ #endif
+ #endif
+
+ /* Public Interface - May be used in end-application: */
+ /* Macros: */
+ /** \name SPI SCK Polarity Configuration Masks */
+ //@{
+ /** SPI clock polarity mask for \ref SPI_Init(). Indicates that the SCK should lead on the rising edge. */
+ #define USART_SPI_SCK_LEAD_RISING (0 << UCPOL1)
+
+ /** SPI clock polarity mask for \ref SPI_Init(). Indicates that the SCK should lead on the falling edge. */
+ #define USART_SPI_SCK_LEAD_FALLING (1 << UCPOL1)
+ //@}
+
+ /** \name SPI Sample Edge Configuration Masks */
+ //@{
+ /** SPI data sample mode mask for \ref SerialSPI_Init(). Indicates that the data should sampled on the leading edge. */
+ #define USART_SPI_SAMPLE_LEADING (0 << UCPHA1)
+
+ /** SPI data sample mode mask for \ref SerialSPI_Init(). Indicates that the data should be sampled on the trailing edge. */
+ #define USART_SPI_SAMPLE_TRAILING (1 << UCPHA1)
+ //@}
+
+ /** \name SPI Data Ordering Configuration Masks */
+ //@{
+ /** SPI data order mask for \ref SerialSPI_Init(). Indicates that data should be shifted out MSB first. */
+ #define USART_SPI_ORDER_MSB_FIRST (0 << UDORD1)
+
+ /** SPI data order mask for \ref SerialSPI_Init(). Indicates that data should be shifted out LSB first. */
+ #define USART_SPI_ORDER_LSB_FIRST (1 << UDORD1)
+ //@}
+
+ /* Inline Functions: */
+ /** Initialize the USART module in Master SPI mode.
+ *
+ * \param[in] SPIOptions USART SPI Options, a mask consisting of one of each of the \c USART_SPI_SCK_*,
+ * \c USART_SPI_SAMPLE_* and \c USART_SPI_ORDER_* masks.
+ * \param[in] BaudRate SPI baud rate, in bits per second.
+ */
+ static inline void SerialSPI_Init(const uint8_t SPIOptions,
+ const uint32_t BaudRate)
+ {
+ DDRD |= ((1 << 3) | (1 << 5));
+ PORTD |= (1 << 2);
+
+ UCSR1C = ((1 << UMSEL11) | (1 << UMSEL10) | SPIOptions);
+ UCSR1B = ((1 << TXEN1) | (1 << RXEN1));
+
+ UBRR1 = SERIAL_SPI_UBBRVAL(BaudRate);
+ }
+
+ /** Turns off the USART driver, disabling and returning used hardware to their default configuration. */
+ static inline void SerialSPI_Disable(void)
+ {
+ UCSR1B = 0;
+ UCSR1A = 0;
+ UCSR1C = 0;
+
+ UBRR1 = 0;
+
+ DDRD &= ~((1 << 3) | (1 << 5));
+ PORTD &= ~(1 << 2);
+ }
+
+ /** Sends and receives a byte through the USART SPI interface, blocking until the transfer is complete.
+ *
+ * \param[in] DataByte Byte to send through the USART SPI interface.
+ *
+ * \return Response byte from the attached SPI device.
+ */
+ static inline uint8_t SerialSPI_TransferByte(const uint8_t DataByte)
+ {
+ UDR1 = DataByte;
+ while (!(UCSR1A & (1 << TXC1)));
+ UCSR1A = (1 << TXC1);
+ return UDR1;
+ }
+
+ /** Sends a byte through the USART SPI interface, blocking until the transfer is complete. The response
+ * byte sent to from the attached SPI device is ignored.
+ *
+ * \param[in] DataByte Byte to send through the USART SPI interface.
+ */
+ static inline void SerialSPI_SendByte(const uint8_t DataByte)
+ {
+ SerialSPI_TransferByte(DataByte);
+ }
+
+ /** Sends a dummy byte through the USART SPI interface, blocking until the transfer is complete. The response
+ * byte from the attached SPI device is returned.
+ *
+ * \return The response byte from the attached SPI device.
+ */
+ static inline uint8_t SerialSPI_ReceiveByte(void)
+ {
+ return SerialSPI_TransferByte(0);
+ }
+
+ /* Disable C linkage for C++ Compilers: */
+ #if defined(__cplusplus)
+ }
+ #endif
+
+#endif
+
+/** @} */
+
diff --git a/lib/lufa/LUFA/Drivers/Peripheral/AVR8/Serial_AVR8.c b/lib/lufa/LUFA/Drivers/Peripheral/AVR8/Serial_AVR8.c
new file mode 100644
index 0000000000..779a80c48c
--- /dev/null
+++ b/lib/lufa/LUFA/Drivers/Peripheral/AVR8/Serial_AVR8.c
@@ -0,0 +1,121 @@
+/*
+ LUFA Library
+ Copyright (C) Dean Camera, 2017.
+
+ dean [at] fourwalledcubicle [dot] com
+ www.lufa-lib.org
+*/
+
+/*
+ Copyright 2017 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 disclaims 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.
+*/
+
+#include "../../../Common/Common.h"
+#if (ARCH == ARCH_AVR8)
+
+#define __INCLUDE_FROM_SERIAL_C
+#include "../Serial.h"
+
+FILE USARTSerialStream;
+
+int Serial_putchar(char DataByte,
+ FILE *Stream)
+{
+ (void)Stream;
+
+ Serial_SendByte(DataByte);
+ return 0;
+}
+
+int Serial_getchar(FILE *Stream)
+{
+ (void)Stream;
+
+ if (!(Serial_IsCharReceived()))
+ return _FDEV_EOF;
+
+ return Serial_ReceiveByte();
+}
+
+int Serial_getchar_Blocking(FILE *Stream)
+{
+ (void)Stream;
+
+ while (!(Serial_IsCharReceived()));
+ return Serial_ReceiveByte();
+}
+
+void Serial_SendString_P(const char* FlashStringPtr)
+{
+ uint8_t CurrByte;
+
+ while ((CurrByte = pgm_read_byte(FlashStringPtr)) != 0x00)
+ {
+ Serial_SendByte(CurrByte);
+ FlashStringPtr++;
+ }
+}
+
+void Serial_SendString(const char* StringPtr)
+{
+ uint8_t CurrByte;
+
+ while ((CurrByte = *StringPtr) != 0x00)
+ {
+ Serial_SendByte(CurrByte);
+ StringPtr++;
+ }
+}
+
+void Serial_SendData(const void* Buffer,
+ uint16_t Length)
+{
+ uint8_t* CurrByte = (uint8_t*)Buffer;
+
+ while (Length--)
+ Serial_SendByte(*(CurrByte++));
+}
+
+void Serial_CreateStream(FILE* Stream)
+{
+ if (!(Stream))
+ {
+ Stream = &USARTSerialStream;
+ stdin = Stream;
+ stdout = Stream;
+ }
+
+ *Stream = (FILE)FDEV_SETUP_STREAM(Serial_putchar, Serial_getchar, _FDEV_SETUP_RW);
+}
+
+void Serial_CreateBlockingStream(FILE* Stream)
+{
+ if (!(Stream))
+ {
+ Stream = &USARTSerialStream;
+ stdin = Stream;
+ stdout = Stream;
+ }
+
+ *Stream = (FILE)FDEV_SETUP_STREAM(Serial_putchar, Serial_getchar_Blocking, _FDEV_SETUP_RW);
+}
+
+#endif
diff --git a/lib/lufa/LUFA/Drivers/Peripheral/AVR8/Serial_AVR8.h b/lib/lufa/LUFA/Drivers/Peripheral/AVR8/Serial_AVR8.h
new file mode 100644
index 0000000000..b3e7ee36a4
--- /dev/null
+++ b/lib/lufa/LUFA/Drivers/Peripheral/AVR8/Serial_AVR8.h
@@ -0,0 +1,271 @@
+/*
+ LUFA Library
+ Copyright (C) Dean Camera, 2017.
+
+ dean [at] fourwalledcubicle [dot] com
+ www.lufa-lib.org
+*/
+
+/*
+ Copyright 2017 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 disclaims 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
+ * \brief Serial USART Peripheral Driver (AVR8)
+ *
+ * On-chip serial USART driver for the 8-bit AVR microcontrollers.
+ *
+ * \note This file should not be included directly. It is automatically included as needed by the USART driver
+ * dispatch header located in LUFA/Drivers/Peripheral/Serial.h.
+ */
+
+/** \ingroup Group_Serial
+ * \defgroup Group_Serial_AVR8 Serial USART Peripheral Driver (AVR8)
+ *
+ * \section Sec_Serial_AVR8_ModDescription Module Description
+ * On-chip serial USART driver for the 8-bit AVR microcontrollers.
+ *
+ * \note This file should not be included directly. It is automatically included as needed by the USART driver
+ * dispatch header located in LUFA/Drivers/Peripheral/Serial.h.
+ *
+ * \section Sec_Serial_AVR8_ExampleUsage Example Usage
+ * The following snippet is an example of how this module may be used within a typical
+ * application.
+ *
+ * \code
+ * // Initialize the serial USART driver before first use, with 9600 baud (and no double-speed mode)
+ * Serial_Init(9600, false);
+ *
+ * // Send a string through the USART
+ * Serial_SendString("Test String\r\n");
+ *
+ * // Send a raw byte through the USART
+ * Serial_SendByte(0xDC);
+ *
+ * // Receive a byte through the USART (or -1 if no data received)
+ * int16_t DataByte = Serial_ReceiveByte();
+ * \endcode
+ *
+ * @{
+ */
+
+#ifndef __SERIAL_AVR8_H__
+#define __SERIAL_AVR8_H__
+
+ /* Includes: */
+ #include "../../../Common/Common.h"
+ #include "../../Misc/TerminalCodes.h"
+
+ #include <stdio.h>
+
+ /* Enable C linkage for C++ Compilers: */
+ #if defined(__cplusplus)
+ extern "C" {
+ #endif
+
+ /* Preprocessor Checks: */
+ #if !defined(__INCLUDE_FROM_SERIAL_H) && !defined(__INCLUDE_FROM_SERIAL_C)
+ #error Do not include this file directly. Include LUFA/Drivers/Peripheral/Serial.h instead.
+ #endif
+
+ /* Private Interface - For use in library only: */
+ #if !defined(__DOXYGEN__)
+ /* External Variables: */
+ extern FILE USARTSerialStream;
+
+ /* Function Prototypes: */
+ int Serial_putchar(char DataByte,
+ FILE *Stream);
+ int Serial_getchar(FILE *Stream);
+ int Serial_getchar_Blocking(FILE *Stream);
+ #endif
+
+ /* Public Interface - May be used in end-application: */
+ /* Macros: */
+ /** Macro for calculating the baud value from a given baud rate when the \c U2X (double speed) bit is
+ * not set.
+ *
+ * \param[in] Baud Target serial UART baud rate.
+ *
+ * \return Closest UBRR register value for the given UART frequency.
+ */
+ #define SERIAL_UBBRVAL(Baud) ((((F_CPU / 16) + (Baud / 2)) / (Baud)) - 1)
+
+ /** Macro for calculating the baud value from a given baud rate when the \c U2X (double speed) bit is
+ * set.
+ *
+ * \param[in] Baud Target serial UART baud rate.
+ *
+ * \return Closest UBRR register value for the given UART frequency.
+ */
+ #define SERIAL_2X_UBBRVAL(Baud) ((((F_CPU / 8) + (Baud / 2)) / (Baud)) - 1)
+
+ /* Function Prototypes: */
+ /** Transmits a given NUL terminated string located in program space (FLASH) through the USART.
+ *
+ * \param[in] FlashStringPtr Pointer to a string located in program space.
+ */
+ void Serial_SendString_P(const char* FlashStringPtr) ATTR_NON_NULL_PTR_ARG(1);
+
+ /** Transmits a given NUL terminated string located in SRAM memory through the USART.
+ *
+ * \param[in] StringPtr Pointer to a string located in SRAM space.
+ */
+ void Serial_SendString(const char* StringPtr) ATTR_NON_NULL_PTR_ARG(1);
+
+ /** Transmits a given buffer located in SRAM memory through the USART.
+ *
+ * \param[in] Buffer Pointer to a buffer containing the data to send.
+ * \param[in] Length Length of the data to send, in bytes.
+ */
+ void Serial_SendData(const void* Buffer, uint16_t Length) ATTR_NON_NULL_PTR_ARG(1);
+
+ /** Creates a standard character stream from the USART so that it can be used with all the regular functions
+ * in the avr-libc \c <stdio.h> library that accept a \c FILE stream as a destination (e.g. \c fprintf). The created
+ * stream is bidirectional and can be used for both input and output functions.
+ *
+ * Reading data from this stream is non-blocking, i.e. in most instances, complete strings cannot be read in by a single
+ * fetch, as the endpoint will not be ready at some point in the transmission, aborting the transfer. However, this may
+ * be used when the read data is processed byte-per-bye (via \c getc()) or when the user application will implement its own
+ * line buffering.
+ *
+ * \param[in,out] Stream Pointer to a FILE structure where the created stream should be placed, if \c NULL, \c stdout
+ * and \c stdin will be configured to use the USART.
+ *
+ * \pre The USART must first be configured via a call to \ref Serial_Init() before the stream is used.
+ */
+ void Serial_CreateStream(FILE* Stream);
+
+ /** Identical to \ref Serial_CreateStream(), except that reads are blocking until the calling stream function terminates
+ * the transfer.
+ *
+ * \param[in,out] Stream Pointer to a FILE structure where the created stream should be placed, if \c NULL, \c stdout
+ * and \c stdin will be configured to use the USART.
+ *
+ * \pre The USART must first be configured via a call to \ref Serial_Init() before the stream is used.
+ */
+ void Serial_CreateBlockingStream(FILE* Stream);
+
+ /* Inline Functions: */
+ /** Initializes the USART, ready for serial data transmission and reception. This initializes the interface to
+ * standard 8-bit, no parity, 1 stop bit settings suitable for most applications.
+ *
+ * \param[in] BaudRate Serial baud rate, in bits per second. This should be the target baud rate regardless of the
+ * \c DoubleSpeed parameter's value.
+ * \param[in] DoubleSpeed Enables double speed mode when set, halving the sample time to double the baud rate.
+ */
+ static inline void Serial_Init(const uint32_t BaudRate,
+ const bool DoubleSpeed);
+ static inline void Serial_Init(const uint32_t BaudRate,
+ const bool DoubleSpeed)
+ {
+ UBRR1 = (DoubleSpeed ? SERIAL_2X_UBBRVAL(BaudRate) : SERIAL_UBBRVAL(BaudRate));
+
+ UCSR1C = ((1 << UCSZ11) | (1 << UCSZ10));
+ UCSR1A = (DoubleSpeed ? (1 << U2X1) : 0);
+ UCSR1B = ((1 << TXEN1) | (1 << RXEN1));
+
+ DDRD |= (1 << 3);
+ PORTD |= (1 << 2);
+ }
+
+ /** Turns off the USART driver, disabling and returning used hardware to their default configuration. */
+ static inline void Serial_Disable(void);
+ static inline void Serial_Disable(void)
+ {
+ UCSR1B = 0;
+ UCSR1A = 0;
+ UCSR1C = 0;
+
+ UBRR1 = 0;
+
+ DDRD &= ~(1 << 3);
+ PORTD &= ~(1 << 2);
+ }
+
+ /** Indicates whether a character has been received through the USART.
+ *
+ * \return Boolean \c true if a character has been received, \c false otherwise.
+ */
+ static inline bool Serial_IsCharReceived(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
+ static inline bool Serial_IsCharReceived(void)
+ {
+ return ((UCSR1A & (1 << RXC1)) ? true : false);
+ }
+
+ /** Indicates whether there is hardware buffer space for a new transmit on the USART. This
+ * function can be used to determine if a call to \ref Serial_SendByte() will block in advance.
+ *
+ * \return Boolean \c true if a character can be queued for transmission immediately, \c false otherwise.
+ */
+ static inline bool Serial_IsSendReady(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
+ static inline bool Serial_IsSendReady(void)
+ {
+ return ((UCSR1A & (1 << UDRE1)) ? true : false);
+ }
+
+ /** Indicates whether the hardware USART transmit buffer is completely empty, indicating all
+ * pending transmissions have completed.
+ *
+ * \return Boolean \c true if no characters are buffered for transmission, \c false otherwise.
+ */
+ static inline bool Serial_IsSendComplete(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE;
+ static inline bool Serial_IsSendComplete(void)
+ {
+ return ((UCSR1A & (1 << TXC1)) ? true : false);
+ }
+
+ /** Transmits a given byte through the USART.
+ *
+ * \note If no buffer space is available in the hardware USART, this function will block. To check if
+ * space is available before calling this function, see \ref Serial_IsSendReady().
+ *
+ * \param[in] DataByte Byte to transmit through the USART.
+ */
+ static inline void Serial_SendByte(const char DataByte) ATTR_ALWAYS_INLINE;
+ static inline void Serial_SendByte(const char DataByte)
+ {
+ while (!(Serial_IsSendReady()));
+ UDR1 = DataByte;
+ }
+
+ /** Receives the next byte from the USART.
+ *
+ * \return Next byte received from the USART, or a negative value if no byte has been received.
+ */
+ static inline int16_t Serial_ReceiveByte(void) ATTR_ALWAYS_INLINE;
+ static inline int16_t Serial_ReceiveByte(void)
+ {
+ if (!(Serial_IsCharReceived()))
+ return -1;
+
+ return UDR1;
+ }
+
+ /* Disable C linkage for C++ Compilers: */
+ #if defined(__cplusplus)
+ }
+ #endif
+
+#endif
+
+/** @} */
+
diff --git a/lib/lufa/LUFA/Drivers/Peripheral/AVR8/TWI_AVR8.c b/lib/lufa/LUFA/Drivers/Peripheral/AVR8/TWI_AVR8.c
new file mode 100644
index 0000000000..eb08687be3
--- /dev/null
+++ b/lib/lufa/LUFA/Drivers/Peripheral/AVR8/TWI_AVR8.c
@@ -0,0 +1,209 @@
+/*
+ LUFA Library
+ Copyright (C) Dean Camera, 2017.
+
+ dean [at] fourwalledcubicle [dot] com
+ www.lufa-lib.org
+*/
+
+/*
+ Copyright 2017 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 disclaims 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.
+*/
+
+#include "../../../Common/Common.h"
+#if (ARCH == ARCH_AVR8) && defined(TWCR)
+
+#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);
+ TimeoutRemaining--;
+ }
+
+ 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);
+ TimeoutRemaining--;
+ }
+
+ 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;
+ }
+ }
+}
+
+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,
+ uint8_t InternalAddressLen,
+ uint8_t* Buffer,
+ uint16_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;
+ }
+ }
+
+ 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,
+ uint16_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;
+}
+
+#endif
diff --git a/lib/lufa/LUFA/Drivers/Peripheral/AVR8/TWI_AVR8.h b/lib/lufa/LUFA/Drivers/Peripheral/AVR8/TWI_AVR8.h
new file mode 100644
index 0000000000..a8b845a5d7
--- /dev/null
+++ b/lib/lufa/LUFA/Drivers/Peripheral/AVR8/TWI_AVR8.h
@@ -0,0 +1,305 @@
+/*
+ LUFA Library
+ Copyright (C) Dean Camera, 2017.
+
+ dean [at] fourwalledcubicle [dot] com
+ www.lufa-lib.org
+*/
+
+/*
+ Copyright 2017 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 disclaims 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
+ * \brief TWI Peripheral Driver (AVR8)
+ *
+ * On-chip TWI driver for the 8-bit AVR microcontrollers.
+ *
+ * \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_AVR8 TWI Peripheral Driver (AVR8)
+ *
+ * \section Sec_TWI_AVR8_ModDescription Module Description
+ * Master mode TWI driver for the 8-bit AVR microcontrollers which contain a hardware TWI module.
+ *
+ * \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.
+ *
+ * \section Sec_TWI_AVR8_ExampleUsage Example Usage
+ * The following snippet is an example of how this module may be used within a typical
+ * application.
+ *
+ * <b>Low Level API Example:</b>
+ * \code
+ * // 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
+ *
+ * <b>High Level API Example:</b>
+ * \code
+ * // 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
+ *
+ * @{
+ */
+
+#ifndef __TWI_AVR8_H__
+#define __TWI_AVR8_H__
+
+ /* Includes: */
+ #include "../../../Common/Common.h"
+
+ #include <stdio.h>
+ #include <util/twi.h>
+
+ /* Enable C linkage for C++ Compilers: */
+ #if defined(__cplusplus)
+ extern "C" {
+ #endif
+
+ /* Preprocessor Checks: */
+ #if !defined(__INCLUDE_FROM_TWI_H) && !defined(__INCLUDE_FROM_TWI_C)
+ #error Do not include this file directly. Include LUFA/Drivers/Peripheral/TWI.h instead.
+ #endif
+
+ #if !(defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB646__) || \
+ defined(__AVR_AT90USB1287__) || defined(__AVR_AT90USB647__) || \
+ defined(__AVR_ATmega16U4__) || defined(__AVR_ATmega32U4__))
+ #error The TWI peripheral driver is not currently available for your selected microcontroller model.
+ #endif
+
+ /* Public Interface - May be used in end-application: */
+ /* Macros: */
+ /** 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 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 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))
+
+ /** Bit length prescaler for \ref TWI_Init(). This mask multiplies the TWI bit length prescaler by 16. */
+ #define TWI_BIT_PRESCALE_16 ((1 << TWPS1) | (0 << TWPS0))
+
+ /** 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
+ {
+ TWI_ERROR_NoError = 0, /**< Indicates that the command completed successfully. */
+ TWI_ERROR_BusFault = 1, /**< A TWI bus fault occurred while attempting to capture the bus. */
+ TWI_ERROR_BusCaptureTimeout = 2, /**< A timeout occurred whilst waiting for the bus to be ready. */
+ TWI_ERROR_SlaveResponseTimeout = 3, /**< No ACK received at the nominated slave address within the timeout period. */
+ 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 <pre>F_CPU / (16 + 2 * BitLength + 4 ^ Prescale)</pre>.
+ *
+ * \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.
+ */
+ static inline void TWI_Init(const uint8_t Prescale,
+ const uint8_t BitLength) ATTR_ALWAYS_INLINE;
+ static inline void TWI_Init(const uint8_t Prescale,
+ const uint8_t BitLength)
+ {
+ TWCR |= (1 << TWEN);
+ TWSR = Prescale;
+ TWBR = BitLength;
+ }
+
+ /** 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_Disable(void) ATTR_ALWAYS_INLINE;
+ static inline void TWI_Disable(void)
+ {
+ TWCR &= ~(1 << TWEN);
+ }
+
+ /** Sends a TWI STOP onto the TWI bus, terminating communication with the currently addressed device. */
+ static inline void TWI_StopTransmission(void) ATTR_ALWAYS_INLINE;
+ static inline void TWI_StopTransmission(void)
+ {
+ 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
+ */
+ bool TWI_SendByte(const uint8_t Byte);
+
+ /** Receives a byte from 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.
+ *
+ * \return Boolean \c true if the byte reception successfully completed, \c false otherwise.
+ */
+ 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.
+ *
+ * \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,
+ uint8_t InternalAddressLen,
+ uint8_t* Buffer,
+ uint16_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.
+ *
+ * \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 write start address is stored
+ * \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,
+ uint16_t Length) ATTR_NON_NULL_PTR_ARG(3);
+
+ /* Disable C linkage for C++ Compilers: */
+ #if defined(__cplusplus)
+ }
+ #endif
+
+#endif
+
+/** @} */
+