lufa working but serial doesnt

master
Ondřej Hruška 2 years ago
commit 4df793ecb2
  1. 10
      .gitignore
  2. 60
      Makefile
  3. 164
      makefile.bak.buggy
  4. 251
      src/Descriptors.c
  5. 138
      src/Descriptors.h
  6. 166
      src/LUFAConfig.h
  7. 242
      src/main.c

10
.gitignore vendored

@ -0,0 +1,10 @@
src/lufa-LUFA-210130
*.bin
*.eep
*.elf
*.hex
*.lss
*.map
*.sym
obj
bin

@ -0,0 +1,60 @@
# https://github.com/jkent/caterina-promicro
VID = 0xbeef
PID = 0x0001
CDEFS = -DDEVICE_VID=$(VID)UL
CDEFS += -DDEVICE_PID=$(PID)UL
MCU = atmega32u4
F_CPU = 16000000
ARCH = AVR8
TARGET = App
SRC = src/main.c src/Descriptors.c $(LUFA_SRC_USB) $(LUFA_SRC_USBCLASS)
F_USB = $(F_CPU)
OPTIMIZATION = s
BOARD = USER
CC_FLAGS = -Isrc -DUSE_LUFA_CONFIG_HEADER -IConfig/ $(CDEFS) -I$(LUFA_PATH)/
CC_FLAGS += -std=gnu99 -mmcu=$(MCU) -DF_CPU=$(F_CPU)UL $(CDEFS)
CC_FLAGS += -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums
CC_FLAGS += -Wall -Wno-main -Wno-strict-prototypes -Wno-comment
CC_FLAGS += -g2 -Wextra -Wfatal-errors -Wno-unused-but-set-variable
CC_FLAGS += -ffunction-sections -fdata-sections -Os $(LUFA_OPTS)
LUFA_PATH = src/lufa-LUFA-210130/LUFA
LD_FLAGS = -Wl,--gc-sections -Wl,--relax
include $(LUFA_PATH)/Build/lufa_core.mk
include $(LUFA_PATH)/Build/lufa_sources.mk
include $(LUFA_PATH)/Build/lufa_build.mk
#include $(LUFA_PATH)/Build/lufa_cppcheck.mk
#include $(LUFA_PATH)/Build/lufa_doxygen.mk
#include $(LUFA_PATH)/Build/lufa_dfu.mk
#include $(LUFA_PATH)/Build/lufa_hid.mk
#include $(LUFA_PATH)/Build/lufa_avrdude.mk
#include $(LUFA_PATH)/Build/lufa_atprogram.mk
PROGRAMMER_TYPE = avr109
PROGRAMMER_ARGS = -P /dev/ttyACM0
AVRDUDE = avrdude
.PHONY: eeprom flash flashe shell
eeprom: $(TARGET).eeprom
%.eeprom: %.elf
$(OBJCOPY) -j .eeprom --change-section-lma .eeprom=0 -O ihex $< $@
flash: $(TARGET).hex
stty -F /dev/ttyACM0 speed 1200
stty -F /dev/ttyACM0 speed 115200
$(AVRDUDE) -c $(PROGRAMMER_TYPE) -p $(MCU) $(PROGRAMMER_ARGS) -U flash:w:$<
flashe: $(TARGET).eeprom
$(AVRDUDE) -c $(PROGRAMMER_TYPE) -p $(MCU) $(PROGRAMMER_ARGS) -U eeprom:w:$<
shell:
$(AVRDUDE) -c $(PROGRAMMER_TYPE) -p $(MCU) $(PROGRAMMER_ARGS) -nt

@ -0,0 +1,164 @@
# https://github.com/jkent/caterina-promicro
## === CPU settings ===
MCU = atmega32u4
F_CPU = 16000000
ARCH = AVR8
TARGET = Target
# Input clock frequency.
# This will define a symbol, F_USB, in all source code files equal to the
# input clock frequency (before any prescaling is performed) in Hz. This value may
# differ from F_CPU if prescaling is used on the latter, and is required as the
# raw input clock is fed directly to the PLL sections of the AVR for high speed
# clock generation for the USB and other AVR subsections. Do NOT tack on a 'UL'
# at the end, this will be done automatically to create a 32-bit value in your
# source code.
#
# If no clock division is performed on the input clock inside the AVR (via the
# CPU clock adjust registers or the clock division fuses), this will be equal to F_CPU.
F_USB = $(F_CPU)
## === Source files ===
# Main C file
APP = app
SRC_DIR=src
INC_DIR=src
OBJ_DIR=obj
BIN_DIR=bin
# LUFA library compile-time options and predefined tokens
LUFA_OPTS = -D USB_DEVICE_ONLY
LUFA_OPTS += -D DEVICE_STATE_AS_GPIOR=0
LUFA_OPTS += -D ORDERED_EP_CONFIG
LUFA_OPTS += -D FIXED_CONTROL_ENDPOINT_SIZE=8
LUFA_OPTS += -D FIXED_NUM_CONFIGURATIONS=1
LUFA_OPTS += -D USE_RAM_DESCRIPTORS
LUFA_OPTS += -D USE_STATIC_OPTIONS="(USB_DEVICE_OPT_FULLSPEED | USB_OPT_REG_ENABLED | USB_OPT_AUTO_PLL)"
LUFA_OPTS += -D NO_INTERNAL_SERIAL
LUFA_OPTS += -D NO_DEVICE_SELF_POWER
LUFA_OPTS += -D NO_DEVICE_REMOTE_WAKEUP
LUFA_OPTS += -D NO_SOF_EVENTS
LUFA_OPTS += -D F_USB=$(F_USB)UL
#LUFA_OPTS += -D NO_BLOCK_SUPPORT
#LUFA_OPTS += -D NO_EEPROM_BYTE_SUPPORT
#LUFA_OPTS += -D NO_FLASH_BYTE_SUPPORT
LUFA_OPTS += -D NO_LOCK_BYTE_WRITE_SUPPORT
LUFA_PATH = src/lufa-LUFA-210130/LUFA
include $(LUFA_PATH)/Build/lufa_core.mk
include $(LUFA_PATH)/Build/lufa_sources.mk
include $(LUFA_PATH)/Build/lufa_build.mk
#include $(LUFA_PATH)/Build/lufa_cppcheck.mk
#include $(LUFA_PATH)/Build/lufa_doxygen.mk
#include $(LUFA_PATH)/Build/lufa_dfu.mk
#include $(LUFA_PATH)/Build/lufa_hid.mk
#include $(LUFA_PATH)/Build/lufa_avrdude.mk
#include $(LUFA_PATH)/Build/lufa_atprogram.mk
## === Programmer ===
#PROGRAMMER_TYPE = arduino
PROGRAMMER_TYPE = avr109
PROGRAMMER_ARGS = -P /dev/ttyACM0
# USB vendor ID (VID)
# SparkFun
VID = 0xbeef
# USB product ID (PID)
PID = 0x0001
CDEFS = -DDEVICE_VID=$(VID)UL
CDEFS += -DDEVICE_PID=$(PID)UL
## === C flags ===
INCFLAGS += -I$(INC_DIR) -I$(LUFA_PATH)/
CFLAGS = -std=gnu99 -mmcu=$(MCU) -DF_CPU=$(F_CPU)UL $(CDEFS)
CFLAGS += -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums
CFLAGS += -Wall -Wno-main -Wno-strict-prototypes -Wno-comment
CFLAGS += -g2 -Wextra -Wfatal-errors -Wno-unused-but-set-variable
CFLAGS += -ffunction-sections -fdata-sections -Os $(LUFA_OPTS)
LFLAGS = -Wl,--gc-sections -Wl,--relax
# CFLAGS += -lm ## Math
# CFLAGS += -Wl,-u,vfprintf -lprintf_flt -lm ## for floating-point printf
# CFLAGS += -Wl,-u,vfprintf -lprintf_min ## for smaller printf
# ---------------------------------------------------------------------------
## Defined programs / locations
CC = avr-gcc
LD = avr-gcc
OBJCOPY = avr-objcopy
OBJDUMP = avr-objdump
AVRSIZE = avr-size
AVRDUDE = avrdude
#$(wildcard $(SRC_DIR)/*.c)
SOURCES=src/main.c src/Descriptors.c $(LUFA_SRC_ALL_FILES)
OBJECTS=$(SOURCES:$(SRC_DIR)/%.c=$(OBJ_DIR)/%.o)
DEPENDS=$(OBJ_DIR)/.depends
TARGET=$(BIN_DIR)/$(APP)
.PHONY: all clean eeprom size
all: $(TARGET).hex size
debug:
@echo "SOURCES $(SOURCES)"
@echo "OBJECTS $(OBJECTS)"
@echo "TARGET $(TARGET)"
eeprom: $(TARGET).eeprom
size: $(TARGET).elf
$(AVRSIZE) -C --mcu=$(MCU) $<
$(TARGET).elf: $(OBJECTS) | $(BIN_DIR)
$(LD) $(CFLAGS) $(LFLGAS) -o $@ $^
%.hex: %.elf
$(OBJCOPY) -R .eeprom -O ihex $< $@
%.eeprom: %.elf
$(OBJCOPY) -j .eeprom --change-section-lma .eeprom=0 -O ihex $< $@
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.c | $(OBJ_DIR)
$(CC) -c $(CFLAGS) $(INCFLAGS) -o $@ $<
$(DEPENDS): $(SOURCES) | $(OBJ_DIR)
$(CC) $(INCFLAGS) -MM $(SOURCES) | sed -e 's!^!$(OBJ_DIR)/!' >$@
$(BIN_DIR):
mkdir -p $@
$(OBJ_DIR):
mkdir -p $@
clean:
rm -rf $(BIN_DIR) $(OBJ_DIR)
## === avrdude ===
flash: $(TARGET).hex
stty -F /dev/ttyACM0 speed 1200
stty -F /dev/ttyACM0 speed 115200
$(AVRDUDE) -c $(PROGRAMMER_TYPE) -p $(MCU) $(PROGRAMMER_ARGS) -U flash:w:$<
flashe: $(TARGET).eeprom
$(AVRDUDE) -c $(PROGRAMMER_TYPE) -p $(MCU) $(PROGRAMMER_ARGS) -U eeprom:w:$<
shell:
$(AVRDUDE) -c $(PROGRAMMER_TYPE) -p $(MCU) $(PROGRAMMER_ARGS) -nt

@ -0,0 +1,251 @@
/*
LUFA Library
Copyright (C) Dean Camera, 2011.
dean [at] fourwalledcubicle [dot] com
www.lufa-lib.org
*/
/*
Copyright 2011 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
*
* USB Device Descriptors, for library use when in USB device mode. Descriptors are special
* computer-readable structures which the host requests upon device enumeration, to determine
* the device's capabilities and functions.
*/
#include "Descriptors.h"
/** Device descriptor structure. This descriptor, located in SRAM memory, describes the overall
* device characteristics, including the supported USB version, control endpoint size and the
* number of device configurations. The descriptor is read out by the USB host when the enumeration
* process begins.
*/
const USB_Descriptor_Device_t DeviceDescriptor =
{
.Header = {.Size = sizeof(USB_Descriptor_Device_t), .Type = DTYPE_Device},
.USBSpecification = VERSION_BCD(1,1,0),
.Class = CDC_CSCP_CDCClass,
.SubClass = CDC_CSCP_NoSpecificSubclass,
.Protocol = CDC_CSCP_NoSpecificProtocol,
.Endpoint0Size = FIXED_CONTROL_ENDPOINT_SIZE,
.VendorID = DEVICE_VID,
.ProductID = DEVICE_PID,
.ReleaseNumber = VERSION_BCD(0,0,1),
.ManufacturerStrIndex = 0x02,
.ProductStrIndex = 0x01,
.SerialNumStrIndex = NO_DESCRIPTOR,
.NumberOfConfigurations = FIXED_NUM_CONFIGURATIONS
};
/** Configuration descriptor structure. This descriptor, located in SRAM memory, describes the usage
* of the device in one of its supported configurations, including information about any device interfaces
* and endpoints. The descriptor is read out by the USB host during the enumeration process when selecting
* a configuration so that the host may correctly communicate with the USB device.
*/
const USB_Descriptor_Configuration_t ConfigurationDescriptor =
{
.Config =
{
.Header = {.Size = sizeof(USB_Descriptor_Configuration_Header_t), .Type = DTYPE_Configuration},
.TotalConfigurationSize = sizeof(USB_Descriptor_Configuration_t),
.TotalInterfaces = 2,
.ConfigurationNumber = 1,
.ConfigurationStrIndex = NO_DESCRIPTOR,
.ConfigAttributes = 0, // USB_CONFIG_ATTR_BUSPOWERED
.MaxPowerConsumption = USB_CONFIG_POWER_MA(100)
},
.CDC_CCI_Interface =
{
.Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
.InterfaceNumber = 0,
.AlternateSetting = 0,
.TotalEndpoints = 1,
.Class = CDC_CSCP_CDCClass,
.SubClass = CDC_CSCP_ACMSubclass,
.Protocol = CDC_CSCP_ATCommandProtocol,
.InterfaceStrIndex = NO_DESCRIPTOR
},
.CDC_Functional_Header =
{
.Header = {.Size = sizeof(USB_CDC_Descriptor_FunctionalHeader_t), .Type = CDC_DTYPE_CSInterface},
.Subtype = 0x00,
.CDCSpecification = VERSION_BCD(1,1,0),
},
.CDC_Functional_ACM =
{
.Header = {.Size = sizeof(USB_CDC_Descriptor_FunctionalACM_t), .Type = CDC_DTYPE_CSInterface},
.Subtype = 0x02,
.Capabilities = 0x04,
},
.CDC_Functional_Union =
{
.Header = {.Size = sizeof(USB_CDC_Descriptor_FunctionalUnion_t), .Type = CDC_DTYPE_CSInterface},
.Subtype = 0x06,
.MasterInterfaceNumber = 0,
.SlaveInterfaceNumber = 1,
},
.CDC_NotificationEndpoint =
{
.Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
.EndpointAddress = (ENDPOINT_DIR_IN | CDC_NOTIFICATION_EPNUM),
.Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
.EndpointSize = CDC_NOTIFICATION_EPSIZE,
.PollingIntervalMS = 0xFF
},
.CDC_DCI_Interface =
{
.Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
.InterfaceNumber = 1,
.AlternateSetting = 0,
.TotalEndpoints = 2,
.Class = CDC_CSCP_CDCDataClass,
.SubClass = CDC_CSCP_NoDataSubclass,
.Protocol = CDC_CSCP_NoDataProtocol,
.InterfaceStrIndex = NO_DESCRIPTOR
},
.CDC_DataOutEndpoint =
{
.Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
.EndpointAddress = (ENDPOINT_DIR_OUT | CDC_RX_EPNUM),
.Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
.EndpointSize = CDC_TXRX_EPSIZE,
.PollingIntervalMS = 0x01
},
.CDC_DataInEndpoint =
{
.Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
.EndpointAddress = (ENDPOINT_DIR_IN | CDC_TX_EPNUM),
.Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
.EndpointSize = CDC_TXRX_EPSIZE,
.PollingIntervalMS = 0x01
}
};
/** Language descriptor structure. This descriptor, located in SRAM memory, is returned when the host requests
* the string descriptor with index 0 (the first index). It is actually an array of 16-bit integers, which indicate
* via the language ID table available at USB.org what languages the device supports for its string descriptors.
*/
const USB_Descriptor_String_t LanguageString =
{
.Header = {.Size = USB_STRING_LEN(1), .Type = DTYPE_String},
.UnicodeString = {LANGUAGE_ID_ENG}
};
/** Product descriptor string. This is a Unicode string containing the product's details in human readable form,
* and is read out upon request by the host when the appropriate string ID is requested, listed in the Device
* Descriptor.
*/
const USB_Descriptor_String_t ProductString =
{
.Header = {.Size = USB_STRING_LEN(5), .Type = DTYPE_String},
.UnicodeString = L"Relay"
};
const USB_Descriptor_String_t ManufNameString =
{
.Header = {.Size = USB_STRING_LEN(10), .Type = DTYPE_String},
.UnicodeString = L"MightyPork"
};
/** This function is called by the library when in device mode, and must be overridden (see LUFA library "USB Descriptors"
* documentation) by the application code so that the address and size of a requested descriptor can be given
* to the USB library. When the device receives a Get Descriptor request on the control endpoint, this function
* is called so that the descriptor details can be passed back and the appropriate descriptor sent back to the
* USB host.
*/
uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue,
const uint16_t wIndex,
const void** const DescriptorAddress)
{
const uint8_t DescriptorType = (wValue >> 8);
const uint8_t DescriptorNumber = (wValue & 0xFF);
const void* Address = NULL;
uint16_t Size = NO_DESCRIPTOR;
switch (DescriptorType)
{
case DTYPE_Device:
Address = &DeviceDescriptor;
Size = sizeof(USB_Descriptor_Device_t);
break;
case DTYPE_Configuration:
Address = &ConfigurationDescriptor;
Size = sizeof(USB_Descriptor_Configuration_t);
break;
case DTYPE_String:
if (!(DescriptorNumber))
{
Address = &LanguageString;
Size = LanguageString.Header.Size;
}
else if (DescriptorNumber == DeviceDescriptor.ProductStrIndex)
{
Address = &ProductString;
Size = ProductString.Header.Size;
} else if (DescriptorNumber == DeviceDescriptor.ManufacturerStrIndex)
{
Address = &ManufNameString;
Size = ManufNameString.Header.Size;
}
break;
}
*DescriptorAddress = Address;
return Size;
}

@ -0,0 +1,138 @@
/*
LUFA Library
Copyright (C) Dean Camera, 2011.
dean [at] fourwalledcubicle [dot] com
www.lufa-lib.org
*/
/*
Copyright 2011 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
*
* Header file for Descriptors.c.
*/
#ifndef _DESCRIPTORS_H_
#define _DESCRIPTORS_H_
/* Includes: */
#include <LUFA/Drivers/USB/USB.h>
/* Macros: */
#if defined(__AVR_AT90USB1287__)
#define AVR_SIGNATURE_1 0x1E
#define AVR_SIGNATURE_2 0x97
#define AVR_SIGNATURE_3 0x82
#elif defined(__AVR_AT90USB647__)
#define AVR_SIGNATURE_1 0x1E
#define AVR_SIGNATURE_2 0x96
#define AVR_SIGNATURE_3 0x82
#elif defined(__AVR_AT90USB1286__)
#define AVR_SIGNATURE_1 0x1E
#define AVR_SIGNATURE_2 0x97
#define AVR_SIGNATURE_3 0x82
#elif defined(__AVR_AT90USB646__)
#define AVR_SIGNATURE_1 0x1E
#define AVR_SIGNATURE_2 0x96
#define AVR_SIGNATURE_3 0x82
#elif defined(__AVR_ATmega32U6__)
#define AVR_SIGNATURE_1 0x1E
#define AVR_SIGNATURE_2 0x95
#define AVR_SIGNATURE_3 0x88
#elif defined(__AVR_ATmega32U4__)
#define AVR_SIGNATURE_1 0x1E
#define AVR_SIGNATURE_2 0x95
#define AVR_SIGNATURE_3 0x87
#elif defined(__AVR_ATmega16U4__)
#define AVR_SIGNATURE_1 0x1E
#define AVR_SIGNATURE_2 0x94
#define AVR_SIGNATURE_3 0x88
#elif defined(__AVR_ATmega32U2__)
#define AVR_SIGNATURE_1 0x1E
#define AVR_SIGNATURE_2 0x95
#define AVR_SIGNATURE_3 0x8A
#elif defined(__AVR_ATmega16U2__)
#define AVR_SIGNATURE_1 0x1E
#define AVR_SIGNATURE_2 0x94
#define AVR_SIGNATURE_3 0x89
#elif defined(__AVR_AT90USB162__)
#define AVR_SIGNATURE_1 0x1E
#define AVR_SIGNATURE_2 0x94
#define AVR_SIGNATURE_3 0x82
#elif defined(__AVR_ATmega8U2__)
#define AVR_SIGNATURE_1 0x1E
#define AVR_SIGNATURE_2 0x93
#define AVR_SIGNATURE_3 0x89
#elif defined(__AVR_AT90USB82__)
#define AVR_SIGNATURE_1 0x1E
#define AVR_SIGNATURE_2 0x94
#define AVR_SIGNATURE_3 0x82
#else
#error The selected AVR part is not currently supported by this bootloader.
#endif
/** Endpoint number for the CDC control interface event notification endpoint. */
#define CDC_NOTIFICATION_EPNUM 2
/** Endpoint number for the CDC data interface TX (data IN) endpoint. */
#define CDC_TX_EPNUM 3
/** Endpoint number for the CDC data interface RX (data OUT) endpoint. */
#define CDC_RX_EPNUM 4
/** Size of the CDC data interface TX and RX data endpoint banks, in bytes. */
#define CDC_TXRX_EPSIZE 16
/** Size of the CDC control interface notification endpoint bank, in bytes. */
#define CDC_NOTIFICATION_EPSIZE 8
/* Type Defines: */
/** Type define for the device configuration descriptor structure. This must be defined in the
* application code, as the configuration descriptor contains several sub-descriptors which
* vary between devices, and which describe the device's usage to the host.
*/
typedef struct
{
USB_Descriptor_Configuration_Header_t Config;
// CDC Control Interface
USB_Descriptor_Interface_t CDC_CCI_Interface;
USB_CDC_Descriptor_FunctionalHeader_t CDC_Functional_Header;
USB_CDC_Descriptor_FunctionalACM_t CDC_Functional_ACM;
USB_CDC_Descriptor_FunctionalUnion_t CDC_Functional_Union;
USB_Descriptor_Endpoint_t CDC_NotificationEndpoint;
// CDC Data Interface
USB_Descriptor_Interface_t CDC_DCI_Interface;
USB_Descriptor_Endpoint_t CDC_DataOutEndpoint;
USB_Descriptor_Endpoint_t CDC_DataInEndpoint;
} USB_Descriptor_Configuration_t;
/* Function Prototypes: */
uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue,
const uint16_t wIndex,
const void** const DescriptorAddress)
ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(3);
#endif

@ -0,0 +1,166 @@
/*
LUFA Library
Copyright (C) Dean Camera, 2021.
dean [at] fourwalledcubicle [dot] com
www.lufa-lib.org
*/
/*
Copyright 2021 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 Library Configuration Header File (Template)
*
* This is a header file which can be used to configure LUFA's
* compile time options, as an alternative to the compile time
* constants supplied through a makefile. To use this configuration
* header, copy this into your project's root directory and supply
* the \c USE_LUFA_CONFIG_HEADER token to the compiler so that it is
* defined in all compiled source files.
*
* For information on what each token does, refer to the LUFA
* manual section "Summary of Compile Tokens".
*/
#ifndef __LUFA_CONFIG_H__
#define __LUFA_CONFIG_H__
#if (ARCH == ARCH_AVR8)
/* Non-USB Related Configuration Tokens: */
// #define DISABLE_TERMINAL_CODES
/* USB Class Driver Related Tokens: */
// #define HID_HOST_BOOT_PROTOCOL_ONLY
// #define HID_STATETABLE_STACK_DEPTH {Insert Value Here}
// #define HID_USAGE_STACK_DEPTH {Insert Value Here}
// #define HID_MAX_COLLECTIONS {Insert Value Here}
// #define HID_MAX_REPORTITEMS {Insert Value Here}
// #define HID_MAX_REPORT_IDS {Insert Value Here}
// #define NO_CLASS_DRIVER_AUTOFLUSH
/* General USB Driver Related Tokens: */
#define ORDERED_EP_CONFIG
#define USE_STATIC_OPTIONS (USB_DEVICE_OPT_FULLSPEED | USB_OPT_REG_ENABLED | USB_OPT_AUTO_PLL)
#define USB_DEVICE_ONLY
// #define USB_HOST_ONLY
// #define USB_STREAM_TIMEOUT_MS {Insert Value Here}
// #define NO_LIMITED_CONTROLLER_CONNECT
#define NO_SOF_EVENTS
/* USB Device Mode Driver Related Tokens: */
#define USE_RAM_DESCRIPTORS
// #define USE_FLASH_DESCRIPTORS
// #define USE_EEPROM_DESCRIPTORS
// #define NO_INTERNAL_SERIAL
#define FIXED_CONTROL_ENDPOINT_SIZE 8
#define DEVICE_STATE_AS_GPIOR 0
#define FIXED_NUM_CONFIGURATIONS 1
// #define CONTROL_ONLY_DEVICE
// #define INTERRUPT_CONTROL_ENDPOINT
#define NO_DEVICE_REMOTE_WAKEUP
#define NO_DEVICE_SELF_POWER
/* USB Host Mode Driver Related Tokens: */
// #define HOST_STATE_AS_GPIOR {Insert Value Here}
// #define USB_HOST_TIMEOUT_MS {Insert Value Here}
// #define HOST_DEVICE_SETTLE_DELAY_MS {Insert Value Here}
// #define NO_AUTO_VBUS_MANAGEMENT
// #define INVERTED_VBUS_ENABLE_LINE
#elif (ARCH == ARCH_XMEGA)
/* Non-USB Related Configuration Tokens: */
// #define DISABLE_TERMINAL_CODES
/* USB Class Driver Related Tokens: */
// #define HID_HOST_BOOT_PROTOCOL_ONLY
// #define HID_STATETABLE_STACK_DEPTH {Insert Value Here}
// #define HID_USAGE_STACK_DEPTH {Insert Value Here}
// #define HID_MAX_COLLECTIONS {Insert Value Here}
// #define HID_MAX_REPORTITEMS {Insert Value Here}
// #define HID_MAX_REPORT_IDS {Insert Value Here}
// #define NO_CLASS_DRIVER_AUTOFLUSH
/* General USB Driver Related Tokens: */
// #define USE_STATIC_OPTIONS {Insert Value Here}
// #define USB_STREAM_TIMEOUT_MS {Insert Value Here}
// #define NO_LIMITED_CONTROLLER_CONNECT
// #define NO_SOF_EVENTS
/* USB Device Mode Driver Related Tokens: */
// #define USE_RAM_DESCRIPTORS
// #define USE_FLASH_DESCRIPTORS
// #define USE_EEPROM_DESCRIPTORS
// #define NO_INTERNAL_SERIAL
// #define FIXED_CONTROL_ENDPOINT_SIZE {Insert Value Here}
// #define DEVICE_STATE_AS_GPIOR {Insert Value Here}
// #define FIXED_NUM_CONFIGURATIONS {Insert Value Here}
// #define CONTROL_ONLY_DEVICE
// #define MAX_ENDPOINT_INDEX {Insert Value Here}
// #define NO_DEVICE_REMOTE_WAKEUP
// #define NO_DEVICE_SELF_POWER
#elif (ARCH == ARCH_UC3)
/* Non-USB Related Configuration Tokens: */
// #define DISABLE_TERMINAL_CODES
/* USB Class Driver Related Tokens: */
// #define HID_HOST_BOOT_PROTOCOL_ONLY
// #define HID_STATETABLE_STACK_DEPTH {Insert Value Here}
// #define HID_USAGE_STACK_DEPTH {Insert Value Here}
// #define HID_MAX_COLLECTIONS {Insert Value Here}
// #define HID_MAX_REPORTITEMS {Insert Value Here}
// #define HID_MAX_REPORT_IDS {Insert Value Here}
// #define NO_CLASS_DRIVER_AUTOFLUSH
/* General USB Driver Related Tokens: */
// #define ORDERED_EP_CONFIG
// #define USE_STATIC_OPTIONS {Insert Value Here}
// #define USB_DEVICE_ONLY
// #define USB_HOST_ONLY
// #define USB_STREAM_TIMEOUT_MS {Insert Value Here}
// #define NO_SOF_EVENTS
/* USB Device Mode Driver Related Tokens: */
// #define NO_INTERNAL_SERIAL
// #define FIXED_CONTROL_ENDPOINT_SIZE {Insert Value Here}
// #define FIXED_NUM_CONFIGURATIONS {Insert Value Here}
// #define CONTROL_ONLY_DEVICE
// #define INTERRUPT_CONTROL_ENDPOINT
// #define NO_DEVICE_REMOTE_WAKEUP
// #define NO_DEVICE_SELF_POWER
/* USB Host Mode Driver Related Tokens: */
// #define USB_HOST_TIMEOUT_MS {Insert Value Here}
// #define HOST_DEVICE_SETTLE_DELAY_MS {Insert Value Here}
// #define NO_AUTO_VBUS_MANAGEMENT
// #define INVERTED_VBUS_ENABLE_LINE
#else
#error Unsupported architecture for this LUFA configuration file.
#endif
#endif

@ -0,0 +1,242 @@
#include <util/delay.h>
#include <avr/io.h>
#include <LUFA/Drivers/USB/USB.h>
#include "Descriptors.h"
#define LED_SETUP() DDRB |= (1<<0); DDRD |= (1<<5);
#define L_LED_OFF() PORTD |= (1<<5)
#define L_LED_ON() PORTD &= ~(1<<5)
#define L_LED_TOGGLE() PORTD ^= (1<<5)
#define DATA_LED_OFF() PORTB |= (1<<0)
#define DATA_LED_ON() PORTB &= ~(1<<0)
/** Endpoint address for the CDC control interface event notification endpoint. */
#define CDC_NOTIFICATION_EPADDR (ENDPOINT_DIR_IN | CDC_NOTIFICATION_EPNUM)
/** Endpoint address for the CDC data interface TX (data IN) endpoint. */
#define CDC_TX_EPADDR (ENDPOINT_DIR_IN | CDC_TX_EPNUM)
/** Endpoint address for the CDC data interface RX (data OUT) endpoint. */
#define CDC_RX_EPADDR (ENDPOINT_DIR_OUT | CDC_RX_EPNUM)
/** Retrieves the next byte from the host in the CDC data OUT endpoint, and clears the endpoint bank if needed
* to allow reception of the next data packet from the host.
*
* \return Next received byte from the host in the CDC data OUT endpoint
*/
static uint8_t FetchNextCommandByte(void)
{
/* Select the OUT endpoint so that the next data byte can be read */
Endpoint_SelectEndpoint(CDC_RX_EPADDR);
/* If OUT endpoint empty, clear it and wait for the next packet from the host */
while (!(Endpoint_IsReadWriteAllowed()))
{
Endpoint_ClearOUT();
while (!(Endpoint_IsOUTReceived()))
{
if (USB_DeviceState == DEVICE_STATE_Unattached)
return 0;
}
}
/* Fetch the next byte from the OUT endpoint */
return Endpoint_Read_8();
}
/** Writes the next response byte to the CDC data IN endpoint, and sends the endpoint back if needed to free up the
* bank when full ready for the next byte in the packet to the host.
*
* \param[in] Response Next response byte to send to the host
*/
static void WriteNextResponseByte(const uint8_t Response)
{
/* Select the IN endpoint so that the next data byte can be written */
Endpoint_SelectEndpoint(CDC_TX_EPADDR);
/* If IN endpoint full, clear it and wait until ready for the next packet to the host */
if (!(Endpoint_IsReadWriteAllowed()))
{
Endpoint_ClearIN();
while (!(Endpoint_IsINReady()))
{
if (USB_DeviceState == DEVICE_STATE_Unattached)
return;
}
}
/* Write the next byte to the IN endpoint */
Endpoint_Write_8(Response);
}
void CDC_Task(void);
/* Pulse generation counters to keep track of the time remaining for each pulse type */
#define DATA_LED_PULSE_PERIOD 100
uint16_t DataLEDPulse = 0; // time remaining for Data LED pulse
uint16_t LLEDPulse;
void LEDPulse(void)
{
LLEDPulse++;
uint8_t p = LLEDPulse >> 8;
if (p > 127)
p = 254-p;
p += p;
if (((uint8_t)LLEDPulse) > p)
L_LED_OFF();
else
L_LED_ON();
}
void main () {
LED_SETUP();
/* Initialize USB Subsystem */
USB_Init();
/* Enable global interrupts so that the USB stack can function */
sei();
for(;;) {
CDC_Task();
USB_USBTask();
LEDPulse();
}
}
/*
* some parts of this code are from LUFA.
*
*
Copyright 2011 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.
*/
// /*
//
// /** Retrieves the next byte from the host in the CDC data OUT endpoint, and clears the endpoint bank if needed
// * to allow reception of the next data packet from the host.
// *
// * \return Next received byte from the host in the CDC data OUT endpoint
// */
// static uint8_t FetchNextCommandByte(void)
// {
// /* Select the OUT endpoint so that the next data byte can be read */
// Endpoint_SelectEndpoint(CDC_RX_EPNUM);
//
// /* If OUT endpoint empty, clear it and wait for the next packet from the host */
// while (!(Endpoint_IsReadWriteAllowed()))
// {
// Endpoint_ClearOUT();
//
// while (!(Endpoint_IsOUTReceived()))
// {
// if (USB_DeviceState == DEVICE_STATE_Unattached)
// return 0;
// }
// }
//
// /* Fetch the next byte from the OUT endpoint */
// return Endpoint_Read_8();
// }
// */
/** Task to read in AVR910 commands from the CDC data OUT endpoint, process them, perform the required actions
* and send the appropriate response back to the host.
*/
void CDC_Task(void)
{
/* Select the OUT endpoint */
Endpoint_SelectEndpoint(CDC_RX_EPNUM);
/* Check if endpoint has a command in it sent from the host */
if (!(Endpoint_IsOUTReceived()))
return;
DATA_LED_ON();
DataLEDPulse = DATA_LED_PULSE_PERIOD;
/* Read in the bootloader command (first byte sent from host) */
uint8_t Command = FetchNextCommandByte();
// COMMAND PROCESSING
if (Command == 'a')
{
WriteNextResponseByte('b');
WriteNextResponseByte('\r');
WriteNextResponseByte('\n');
}
/* Select the IN endpoint */
Endpoint_SelectEndpoint(CDC_TX_EPNUM);
/* Remember if the endpoint is completely full before clearing it */
bool IsEndpointFull = !(Endpoint_IsReadWriteAllowed());
/* Send the endpoint data to the host */
Endpoint_ClearIN();
/* If a full endpoint's worth of data was sent, we need to send an empty packet afterwards to signal end of transfer */
if (IsEndpointFull)
{
while (!(Endpoint_IsINReady()))
{
if (USB_DeviceState == DEVICE_STATE_Unattached)
return;
}
Endpoint_ClearIN();
}
/* Wait until the data has been sent to the host */
while (!(Endpoint_IsINReady()))
{
if (USB_DeviceState == DEVICE_STATE_Unattached)
return;
}
/* Select the OUT endpoint */
Endpoint_SelectEndpoint(CDC_RX_EPNUM);
/* Acknowledge the command from the host */
Endpoint_ClearOUT();
}
Loading…
Cancel
Save