Commit 2a820d23 authored by Sebastian Neuser's avatar Sebastian Neuser

Implement LED driver

parent 8309c51e
/*
LUFA Library
Copyright (C) Dean Camera, 2018.
dean [at] fourwalledcubicle [dot] com
www.lufa-lib.org
*/
/*
Copyright 2018 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 LUFA Custom Board LED Hardware Driver (Template)
*
* This is a stub driver header file, for implementing custom board
* layout hardware with compatible LUFA board specific drivers. If
* the library is configured to use the BOARD_USER board mode, this
* driver file should be completed and copied into the "/Board/" folder
* inside the application's folder.
*
* This stub is for the board-specific component of the LUFA LEDs driver,
* for the LEDs (up to four) mounted on most development boards.
*/
#ifndef __LEDS_USER_H__
#define __LEDS_USER_H__
/* Includes: */
/* Enable C linkage for C++ Compilers: */
#if defined(__cplusplus)
extern "C" {
#endif
/* Preprocessor Checks: */
#if !defined(__INCLUDE_FROM_LEDS_H)
#error Do not include this file directly. Include LUFA/Drivers/Board/LEDS.h instead.
#endif
/* Public Interface - May be used in end-application: */
/* Macros: */
/** LED mask for the first LED on the board. */
#define LEDS_LEDR (1 << 5)
/** LED mask for the second LED on the board. */
#define LEDS_LEDG (1 << 7)
/** LED mask for the third LED on the board. */
#define LEDS_LEDB (1 << 6)
/** LED mask for all the LEDs on the board. */
#define LEDS_ALL_LEDS (LEDS_LEDR | LEDS_LEDG | LEDS_LEDB)
/** LED mask for none of the board LEDs. */
#define LEDS_NO_LEDS 0
/* Inline Functions: */
#if !defined(__DOXYGEN__)
static inline void LEDs_Init(void)
{
DDRB |= LEDS_ALL_LEDS;
PORTB |= LEDS_ALL_LEDS;
}
static inline void LEDs_Disable(void)
{
DDRB &= ~LEDS_ALL_LEDS;
PORTB &= ~LEDS_ALL_LEDS;
}
static inline void LEDs_TurnOnLEDs(const uint8_t LedMask)
{
PORTB &= ~LedMask;
}
static inline void LEDs_TurnOffLEDs(const uint8_t LedMask)
{
PORTB |= LedMask;
}
static inline void LEDs_SetAllLEDs(const uint8_t LedMask)
{
PORTB = ((PORTB | LEDS_ALL_LEDS) & ~LedMask);
}
static inline void LEDs_ChangeLEDs(const uint8_t LedMask,
const uint8_t ActiveMask)
{
PORTB = ((PORTB | LedMask) & ~ActiveMask);
}
static inline void LEDs_ToggleLEDs(const uint8_t LEDMask)
{
PINB = LEDMask;
}
static inline uint8_t LEDs_GetLEDs(void) ATTR_WARN_UNUSED_RESULT;
static inline uint8_t LEDs_GetLEDs(void)
{
return (PORTB & LEDS_ALL_LEDS);
}
#endif
/* Disable C linkage for C++ Compilers: */
#if defined(__cplusplus)
}
#endif
#endif
///\file
///\brief Driver for the two RGB LEDs on the ProgBob board
#include <stdbool.h>
#include <stdint.h>
#include <avr/interrupt.h>
#include "LEDs.h"
///\brief LED update frequency in [Hz]
#define F_UPDATE 60
///\brief Maximum LED intensity fade frequency in [Hz]
#define INITIAL_LED_STATE { .intensity = MAX_INTENSITY }
///\brief Maximum LED intensity
#define MAX_INTENSITY UINT8_MAX
///\brief Determines if an LED output should be enabled
///\param led
/// LED state
///\param rgb
/// "red", "green" or "blue"
#define LED_OUTPUT_ENABLED(led, rgb) (counter < ((uint16_t) led.color.rgb * led.intensity) >> 8)
///\brief Color intensity lookup table
///\details Generated with Haskell: [round $ 1.02198**x - 1 | x <- [0..255]]
static const uint8_t intensity_lookup_table[] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3,
3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5,
5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 7, 7, 7,
7, 7, 7, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 10, 10, 10,
10, 11, 11, 11, 11, 12, 12, 12, 13, 13, 13, 14, 14, 14, 14, 15,
15, 16, 16, 16, 17, 17, 17, 18, 18, 19, 19, 20, 20, 20, 21, 21,
22, 22, 23, 23, 24, 25, 25, 26, 26, 27, 27, 28, 29, 29, 30, 31,
31, 32, 33, 34, 34, 35, 36, 37, 38, 38, 39, 40, 41, 42, 43, 44,
45, 46, 47, 48, 49, 50, 51, 52, 54, 55, 56, 57, 59, 60, 61, 63,
64, 65, 67, 68, 70, 71, 73, 75, 76, 78, 80, 82, 83, 85, 87, 89,
91, 93, 95, 97, 99, 102, 104, 106, 109, 111, 113, 116, 118, 121, 124, 127,
129, 132, 135, 138, 141, 144, 148, 151, 154, 158, 161, 165, 168, 172, 176, 180,
184, 188, 192, 196, 200, 205, 209, 214, 219, 223, 228, 233, 239, 244, 249, 255
};
///\brief Ramp direction
enum direction {
DOWN = -1,
CONST = 0,
UP = 1,
};
///\brief RGB color
union rgb_color {
struct {
uint8_t blue;
uint8_t green;
uint8_t red;
};
uint32_t raw;
};
///\brief RGB led state
struct led_state {
union rgb_color color;
uint8_t intensity;
uint8_t clock_counter; ///< Intensity update clock division counter
uint8_t clock_divisor; ///< Intensity update clock divisor
enum direction intensity_step; ///< Intensity ramp state
};
///\brief Current state of the left RGB LED
static struct led_state left_led = INITIAL_LED_STATE;
///\brief Current state of the right RGB LED
static struct led_state right_led = INITIAL_LED_STATE;
///\brief Fading disable state
static bool fading_disabled = false;
///\brief Helper function for LED port mask construction
///\details Masks one bit in a PORT register bitmask
///\param mask
/// register mask to modify
///\param bit
/// bit to set / clear
///\param set
/// bit value
static inline void mask_led_bit(uint8_t* const mask, const uint8_t bit, const uint8_t set)
{
if (set) {
*mask &=~ bit;
}
else {
*mask |= bit;
}
}
///\brief Resets the fader for an LED
///\param led
/// the LED to reset
///\param divisor
/// fade clock divisor
static inline void reset_fader(struct led_state* const led, const uint8_t divisor)
{
led->clock_divisor = divisor;
led->clock_counter = led->clock_divisor;
led->intensity = MAX_INTENSITY;
led->intensity_step = led->clock_divisor ? DOWN : CONST;
}
///\brief Updates an LED's intensity if it is in pulsating mode
///\details Call frequency: F_UPDATE * MAX_INTENSITY
static inline void update_intensity(struct led_state* const led)
{
// Check if pulsating mode is enabled
if (led->intensity_step == CONST) {
return;
}
// Divide clock
--led->clock_counter;
if (led->clock_counter > 0) {
return;
}
led->clock_counter = led->clock_divisor;
// Generate intensity triangle wave
if (led->intensity_step == UP && led->intensity == MAX_INTENSITY) {
led->intensity_step = DOWN;
}
else if (led->intensity_step == DOWN && led->intensity == 0) {
led->intensity_step = UP;
}
led->intensity += led->intensity_step;
}
///\brief Updates the AVR's LED output pins
///\details Call frequency: F_UPDATE * MAX_INTENSITY
static inline void update_ports(void)
{
static uint8_t counter = 0;
++counter;
uint8_t port_left = LEDS_PORT_LEFT;
uint8_t port_right = LEDS_PORT_RIGHT;
if (fading_disabled) {
port_left &=~ LEDS_MASK_LEFT;
port_left |= counter < left_led.color.red ? 0 : LEDS_LED_LR;
port_left |= counter < left_led.color.green ? 0 : LEDS_LED_LG;
port_left |= counter < left_led.color.blue ? 0 : LEDS_LED_LB;
port_right &=~ LEDS_MASK_RIGHT;
port_right |= counter < right_led.color.red ? 0 : LEDS_LED_RR;
port_right |= counter < right_led.color.green ? 0 : LEDS_LED_RG;
port_right |= counter < right_led.color.blue ? 0 : LEDS_LED_RB;
}
else {
mask_led_bit(&port_left, LEDS_LED_LR, LED_OUTPUT_ENABLED(left_led, red));
mask_led_bit(&port_left, LEDS_LED_LG, LED_OUTPUT_ENABLED(left_led, green));
mask_led_bit(&port_left, LEDS_LED_LB, LED_OUTPUT_ENABLED(left_led, blue));
mask_led_bit(&port_right, LEDS_LED_RR, LED_OUTPUT_ENABLED(right_led, red));
mask_led_bit(&port_right, LEDS_LED_RG, LED_OUTPUT_ENABLED(right_led, green));
mask_led_bit(&port_right, LEDS_LED_RB, LED_OUTPUT_ENABLED(right_led, blue));
}
LEDS_PORT_LEFT = port_left;
LEDS_PORT_RIGHT = port_right;
}
ISR(TIMER1_COMPA_vect)
{
if (!fading_disabled) {
update_intensity(&left_led);
update_intensity(&right_led);
}
update_ports();
}
void leds_disable_fading(const bool disable)
{
fading_disabled = disable;
if (!fading_disabled) {
reset_fader(&left_led, left_led.clock_divisor);
reset_fader(&right_led, right_led.clock_divisor);
}
}
void leds_init(void)
{
LEDS_DDR_LEFT |= LEDS_MASK_LEFT;
LEDS_PORT_LEFT |= LEDS_MASK_LEFT;
LEDS_DDR_RIGHT |= LEDS_MASK_RIGHT;
LEDS_PORT_RIGHT |= LEDS_MASK_RIGHT;
TCCR1A = 0;
TCCR1B = (1 << WGM12) | (1 << CS11) | (1 << CS10); // CTC (OCRA), F_CPU / 64
OCR1A = F_CPU / 64 / MAX_INTENSITY / F_UPDATE - 1;
TIMSK1 = (1 << OCIE1A);
}
void leds_set_color(const enum leds_led led, const uint32_t rgb)
{
union rgb_color color = { .raw = rgb};
struct led_state* const state = led == LEDS_LED_LEFT ? &left_led : &right_led;
state->color.red = intensity_lookup_table[color.red];
state->color.green = intensity_lookup_table[color.green];
state->color.blue = intensity_lookup_table[color.blue];
}
void leds_set_fade_frequency(const enum leds_led led, const uint8_t frequency)
{
struct led_state* const state = led == LEDS_LED_LEFT ? &left_led : &right_led;
if (frequency == 0) {
state->clock_divisor = 0;
state->intensity_step = CONST;
return;
}
uint8_t divisor = F_UPDATE / frequency;
if (state->clock_divisor != divisor) {
reset_fader(state, divisor);
}
}
///\file
///\brief Driver for the two RGB LEDs on the ProgBob board
#ifndef LEDS_H
#define LEDS_H
#include <stdbool.h>
#include <stdint.h>
#include <avr/io.h>
///\brief Bitmask for the left red LED
#define LEDS_LED_LR (1 << 4)
///\brief Bitmask for the left green LED
#define LEDS_LED_LG (1 << 6)
///\brief Bitmask for the left blue LED
#define LEDS_LED_LB (1 << 5)
///\brief Bitmask for all left LEDs
#define LEDS_MASK_LEFT (LEDS_LED_LR | LEDS_LED_LG | LEDS_LED_LB)
///\brief DDR register for left LEDs
#define LEDS_DDR_LEFT DDRC
///\brief PORT register for left LEDs
#define LEDS_PORT_LEFT PORTC
///\brief Bitmask for the right red LED
#define LEDS_LED_RR (1 << 5)
///\brief Bitmask for the right green LED
#define LEDS_LED_RG (1 << 7)
///\brief Bitmask for the right blue LED
#define LEDS_LED_RB (1 << 6)
///\brief Bitmask for all left LEDs
#define LEDS_MASK_RIGHT (LEDS_LED_RR | LEDS_LED_RG | LEDS_LED_RB)
///\brief DDR register for right LEDs
#define LEDS_DDR_RIGHT DDRB
///\brief PORT register for right LEDs
#define LEDS_PORT_RIGHT PORTB
///\brief Available RGB LEDs
enum leds_led {
LEDS_LED_LEFT,
LEDS_LED_RIGHT,
};
///\brief Colors used to indicate things
enum leds_color {
LEDS_COLOR_BOB3_CONNECTED = 0x008800, ///< green: BOB3 board connected
LEDS_COLOR_BOB3_NOT_CONNECTED = 0xaa0000, ///< red: BOB3 board not connected
LEDS_COLOR_BOB3_PROGRAMMING = 0x880088, ///< magenta: USB interface is busy
LEDS_COLOR_USB_ENUMERATING = 0xaa8800, ///< yellow: USB interface is enumerating
LEDS_COLOR_USB_ERROR = 0xaa0000, ///< red: Error in USB interface
LEDS_COLOR_USB_NOT_READY = 0x0000aa, ///< blue: USB interface is not ready
LEDS_COLOR_USB_READY = 0x008800, ///< green: USB interface is ready
};
///\brief En-/disables LED fading
///\param disable
/// if `true`, fading of LED intensity is paused
void leds_disable_fading(bool disable);
///\brief Configures LED GPIOS as output and sets up a timer interrupt for PWM generation.
void leds_init(void);
///\brief Sets an LED's color
///\param led
/// the LED to configure
///\param color
/// the color to set as 0xRRGGBB
void leds_set_color(enum leds_led led, uint32_t color);
///\brief Sets an LED's intensity fade frequency
///\param led
/// the LED to configure
///\param frequency
/// frequency in [Hz]; `0` disables fading
void leds_set_fade_frequency(enum leds_led led, uint8_t frequency);
#endif
......@@ -115,9 +115,10 @@ static volatile uint8_t SoftSPI_BitsRemaining;
/** ISR to handle software SPI transmission and reception */
/*
ISR(TIMER1_COMPA_vect, ISR_BLOCK)
{
/* Check if rising edge (output next bit) or falling edge (read in next bit) */
// Check if rising edge (output next bit) or falling edge (read in next bit)
if (!(PINB & (1 << 1)))
{
if (SoftSPI_Data & (1 << 7))
......@@ -139,9 +140,10 @@ ISR(TIMER1_COMPA_vect, ISR_BLOCK)
SoftSPI_Data |= (1 << 0);
}
/* Fast toggle of PORTB.1 via the PIN register (see datasheet) */
// Fast toggle of PORTB.1 via the PIN register (see datasheet)
PINB |= (1 << 1);
}
*/
/** Initializes the appropriate SPI driver (hardware or software, depending on the selected ISP speed) ready for
* communication with the attached target.
......
......@@ -13,13 +13,16 @@
MCU = at90usb162
ARCH = AVR8
BOARD = USER
BOARD = NONE
F_CPU = 16000000
F_USB = $(F_CPU)
OPTIMIZATION = s
TARGET = ProgBob
SRC = $(TARGET).c AVRISPDescriptors.c Lib/V2Protocol.c Lib/V2ProtocolParams.c Lib/ISP/ISPProtocol.c Lib/ISP/ISPTarget.c Lib/XPROG/XPROGProtocol.c \
Lib/XPROG/XPROGTarget.c Lib/XPROG/XMEGANVM.c Lib/XPROG/TINYNVM.c $(LUFA_SRC_USB)
SRC = $(TARGET).c LEDs.c AVRISPDescriptors.c \
Lib/V2Protocol.c Lib/V2ProtocolParams.c \
Lib/ISP/ISPProtocol.c Lib/ISP/ISPTarget.c\
Lib/XPROG/XPROGProtocol.c Lib/XPROG/XPROGTarget.c Lib/XPROG/XMEGANVM.c Lib/XPROG/TINYNVM.c \
$(LUFA_SRC_USB)
LUFA_PATH = Lib/lufa/LUFA
CC_FLAGS = -DUSE_LUFA_CONFIG_HEADER -IConfig/
LD_FLAGS =
......@@ -42,3 +45,6 @@ include $(DMBS_PATH)/gcc.mk
include $(DMBS_PATH)/hid.mk
include $(DMBS_PATH)/avrdude.mk
include $(DMBS_PATH)/atprogram.mk
program:
avrdude -p usb162 -c avrispmkII -P /dev/ttyACM0 -U flash:w:$(TARGET).hex:i
......@@ -34,74 +34,97 @@
* the project and is responsible for the initial application hardware configuration.
*/
#include "ProgBob.h"
#if (BOARD != BOARD_NONE)
/* Some board hardware definitions (e.g. the Arduino Micro) have their LEDs defined on the same pins
as the ISP, PDI or TPI interfaces (see the accompanying project documentation). If a board other
than NONE is selected (to enable the LED driver with the programmer) you should double-check that
no conflicts will occur. If there is a conflict, turn off the LEDs (set BOARD to NONE in the makefile)
or define a custom board driver (see the LUFA manual) with alternative LED mappings.
*/
#warning Board specific drivers have been selected; make sure the board LED driver does not conflict with the programmer ISP/PDI/TPI interfaces.
#endif
/** Main program entry point. This routine contains the overall program flow, including initial
* setup of all components and the main program loop.
*/
int main(void)
#include <avr/io.h>
#include <avr/wdt.h>
#include <avr/power.h>
#include <LUFA/Drivers/USB/USB.h>
#include <LUFA/Platform/Platform.h>
#include "Config/AppConfig.h"
#include "Lib/V2Protocol.h"
#include "AVRISPDescriptors.h"
#include "LEDs.h"
#define PROTOCOL_TIMEOUT 10000
///\brief Processes incoming STK500v2 protocol commands
static void avrisp_task(void)
{
SetupHardware();
V2Protocol_Init();
/* Device must be connected and configured for the task to run */
if (USB_DeviceState != DEVICE_STATE_Configured)
return;
LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
GlobalInterruptEnable();
V2Params_UpdateParamValues();
for (;;)
Endpoint_SelectEndpoint(AVRISP_DATA_OUT_EPADDR);
/* Check to see if a V2 Protocol command has been received */
static uint32_t timeout = 0;
if (Endpoint_IsOUTReceived())
{
#if (BOARD == BOARD_USBTINYMKII)
/* On the USBTINY-MKII target, there is a secondary LED which indicates the current selected power
mode - either VBUS, or sourced from the VTARGET pin of the programming connectors */
LEDs_ChangeLEDs(LEDMASK_VBUSPOWER, (PIND & (1 << 0)) ? 0 : LEDMASK_VBUSPOWER);
#endif
if (timeout == 0) {
leds_disable_fading(true);
leds_set_color(LEDS_LED_RIGHT, LEDS_COLOR_BOB3_PROGRAMMING);
}
timeout = PROTOCOL_TIMEOUT;
AVRISP_Task();
USB_USBTask();
/* Pass off processing of the V2 Protocol command to the V2 Protocol handler */
V2Protocol_ProcessCommand();
}
else {
if (timeout == 0) {
return;
}
--timeout;
if (timeout == 0) {
leds_disable_fading(false);
}
}
}
/** Configures the board hardware and chip peripherals for the demo's functionality. */
void SetupHardware(void)
///\brief Main program entry point
int main(void)
{
#if (ARCH == ARCH_AVR8)
/* Disable watchdog if enabled by bootloader/fuses */
// Disable watchdog if enabled by bootloader/fuses
MCUSR &= ~(1 << WDRF);
wdt_disable();
/* Disable clock division */
// Disable clock division
clock_prescale_set(clock_div_1);
#endif
/* Hardware Initialization */
LEDs_Init();
#if defined(RESET_TOGGLES_LIBUSB_COMPAT)
UpdateCurrentCompatibilityMode();
#endif
/* USB Stack Initialization */
// Hardware initialization
leds_init();
leds_set_color(LEDS_LED_LEFT, LEDS_COLOR_USB_NOT_READY);
leds_set_color(LEDS_LED_RIGHT, LEDS_COLOR_BOB3_NOT_CONNECTED);
leds_set_fade_frequency(LEDS_LED_RIGHT, 1);
USB_Init();
V2Protocol_Init();
GlobalInterruptEnable();
for (;;)
{
USB_USBTask();
avrisp_task();
}
return 0;
}
/** Event handler for the library USB Connection event. */
void EVENT_USB_Device_Connect(void)
{
LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);
leds_set_color(LEDS_LED_LEFT, LEDS_COLOR_USB_ENUMERATING);
}
/** Event handler for the library USB Disconnection event. */
void EVENT_USB_Device_Disconnect(void)
{
LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
leds_set_color(LEDS_LED_LEFT, LEDS_COLOR_USB_NOT_READY);
}
/** Event handler for the library USB Configuration Changed event. */
......@@ -117,30 +140,7 @@ void EVENT_USB_Device_ConfigurationChanged(void)
ConfigSuccess &= Endpoint_ConfigureEndpoint(AVRISP_DATA_IN_EPADDR, EP_TYPE_BULK, AVRISP_DATA_EPSIZE, 1);
/* Indicate endpoint configuration success or failure */
LEDs_SetAllLEDs(ConfigSuccess ? LEDMASK_USB_READY : LEDMASK_USB_ERROR);
}
/** Processes incoming V2 Protocol commands from the host, returning a response when required. */
void AVRISP_Task(void)
{
/* Device must be connected and configured for the task to run */
if (USB_DeviceState != DEVICE_STATE_Configured)
return;
V2Params_UpdateParamValues();
Endpoint_SelectEndpoint(AVRISP_DATA_OUT_EPADDR);
/* Check to see if a V2 Protocol command has been received */
if (Endpoint_IsOUTReceived())
{
LEDs_SetAllLEDs(LEDMASK_BUSY);
/* Pass off processing of the V2 Protocol command to the V2 Protocol handler */
V2Protocol_ProcessCommand();
LEDs_SetAllLEDs(LEDMASK_USB_READY);
}
leds_set_color(LEDS_LED_LEFT, ConfigSuccess ? LEDS_COLOR_USB_READY : LEDS_COLOR_USB_ERROR);
}
/** This function is called by the library when in device mode, and must be overridden (see library "USB Descriptors"
......
/*
LUFA Library
Copyright (C) Dean Camera, 2018.
dean [at] fourwalledcubicle [dot] com
www.lufa-lib.org
*/
/*
Copyright 2018 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
*
* Header file for AVRISP.c.
*/
#ifndef _AVRISP_H_
#define _AVRISP_H_
/* Includes: */
#include <avr/io.h>
#include <avr/wdt.h>
#include <avr/interrupt.h>
#include <avr/power.h>
#include <LUFA/Drivers/Board/LEDs.h>
#include <LUFA/Drivers/USB/USB.h>
#include <LUFA/Platform/Platform.h>
#if defined(ADC)
#include <LUFA/Drivers/Peripheral/ADC.h>
#endif
#include "AVRISPDescriptors.h"
#include "Lib/V2Protocol.h"
#include "Config/AppConfig.h"
/* Macros: */
/** LED mask for the library LED driver, to indicate that the USB interface is not ready. */
#define LEDMASK_USB_NOTREADY (LEDS_LEDG | LEDS_LEDB) // cyan
/** LED mask for the library LED driver, to indicate that the USB interface is enumerating. */
#define LEDMASK_USB_ENUMERATING (LEDS_LEDR | LEDS_LEDG) // yellow
/** LED mask for the library LED driver, to indicate that the USB interface is ready. */
#define LEDMASK_USB_READY LEDS_LEDG
/** LED mask for the library LED driver, to indicate that an error has occurred in the USB interface. */
#define LEDMASK_USB_ERROR LEDS_LEDR
/** LED mask for the library LED driver, to indicate that the USB interface is busy. */
#define LEDMASK_BUSY (LEDS_LEDR | LEDS_LEDB) // magenta
/** LED mask for the library LED driver, to indicate that the target is being powered by VBUS. */
#define LEDMASK_VBUSPOWER LEDS_LEDB
/* Function Prototypes: */
void SetupHardware(void);
void AVRISP_Task(void);
void EVENT_USB_Device_Connect(void);
void EVENT_USB_Device_Disconnect(void);
void EVENT_USB_Device_ConfigurationChanged(void);
uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue,