From 22bb178687a2c86b4fdc9c5ea9203c0e3b140003 Mon Sep 17 00:00:00 2001 From: Valentin Ochs Date: Wed, 16 Aug 2023 21:07:52 +0200 Subject: [PATCH] Initial commit --- .gitignore | 8 ++ .gitmodules | 3 + Config/LUFAConfig.h | 7 ++ board.h | 34 +++++++++ commands.c | 114 ++++++++++++++++++++++++++++ commands.h | 16 ++++ descriptors.c | 180 ++++++++++++++++++++++++++++++++++++++++++++ descriptors.h | 110 +++++++++++++++++++++++++++ lufa | 1 + main.c | 141 ++++++++++++++++++++++++++++++++++ main.h | 22 ++++++ makefile | 42 +++++++++++ usb.c | 70 +++++++++++++++++ usb.h | 3 + 14 files changed, 751 insertions(+) create mode 100644 .gitignore create mode 100644 .gitmodules create mode 100644 Config/LUFAConfig.h create mode 100644 board.h create mode 100644 commands.c create mode 100644 commands.h create mode 100644 descriptors.c create mode 100644 descriptors.h create mode 160000 lufa create mode 100644 main.c create mode 100644 main.h create mode 100644 makefile create mode 100644 usb.c create mode 100644 usb.h diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..30ade4e --- /dev/null +++ b/.gitignore @@ -0,0 +1,8 @@ +BaitAndSwitch.bin +BaitAndSwitch.eep +BaitAndSwitch.elf +BaitAndSwitch.hex +BaitAndSwitch.lss +BaitAndSwitch.map +BaitAndSwitch.sym +obj diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..b6a8475 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "lufa"] + path = lufa + url = https://github.com/abcminiuser/lufa.git diff --git a/Config/LUFAConfig.h b/Config/LUFAConfig.h new file mode 100644 index 0000000..88bda00 --- /dev/null +++ b/Config/LUFAConfig.h @@ -0,0 +1,7 @@ +#pragma once +#define USE_STATIC_OPTIONS (USB_DEVICE_OPT_FULLSPEED | USB_OPT_REG_ENABLED | USB_OPT_AUTO_PLL) +#define USB_DEVICE_ONLY +#define USE_FLASH_DESCRIPTORS +#define FIXED_CONTROL_ENDPOINT_SIZE 8 +#define FIXED_NUM_CONFIGURATIONS 1 +#define INTERRUPT_CONTROL_ENDPOINT diff --git a/board.h b/board.h new file mode 100644 index 0000000..1dda11a --- /dev/null +++ b/board.h @@ -0,0 +1,34 @@ +#pragma once +#include +#include + +extern FILE USBSerialStream; + +#define SET_FUN_N(NAME, PORT, PIN) inline static void NAME(void) { PORT |= (1< + +extern FILE USBSerialStream; + +static void DB(char const *s) { + if (connected) { + fputs(s, &USBSerialStream); + fputs("\r\n", &USBSerialStream); + } +} + +void connectCTL(void) { + DB("CC"); + connectPowerCTL(); + disconnectPowerDUT(); + connectDataCTL(); +} + +void connectDUT(void) { + DB("CD"); + connectPowerDUT(); + disconnectPowerCTL(); + connectDataDUT(); +} + +void connectDataCTL(void) { + DB("CDC"); + PortBIndOff(); + CtrlDataOn(); + OutEnOn(); + PortAIndOn(); +} + +void connectDataDUT(void) { + DB("CDD"); + PortAIndOff(); + DutDataOn(); + OutEnOn(); + PortBIndOn(); +} + +void connectPowerCTL(void) { + DB("CPC"); + PortAPowOn(); +} + +void connectPowerDUT(void) { + DB("CPD"); + PortBPowOn(); +} + +void disconnect(void) { + DB("D"); + disconnectData(); + disconnectPower(); +} + +void disconnectData(void) { + DB("DD"); + OutEnOff(); + PortAIndOff(); + PortBIndOff(); +} + +void disconnectPower(void) { + DB("DP"); + disconnectPowerCTL(); + disconnectPowerDUT(); +} + +void disconnectPowerCTL(void) { + DB("DPC"); + PortAPowOff(); +} + +void disconnectPowerDUT(void) { + DB("DPD"); + PortBPowOff(); +} + +void clearID(void) { + DB("CI"); + SysLedOff(); +} + +void setID(void) { + DB("SI"); + SysLedOn(); +} + +void status(void) { + char buf[30]; + snprintf(buf, sizeof buf, + "PC:%d, PD:%d, " + "DT:%s\r\n" + , PortAPowPort(), PortBPowPort() + , OutEnPort() ? (CtrlDataPort() ? "Ctrl" : "DUT") : "off" + ); + CDC_Device_SendString(&VirtualSerial_CDC_Interface, buf); +} + +void debug(void) { + char buf[20]; + snprintf(buf, sizeof buf, + "(%02x %02x %02x)\r\n" + , (unsigned) (PINB & 0x87), (unsigned) (PINC & 0xF6), (unsigned) (PIND & 0xFF) + ); + CDC_Device_SendString(&VirtualSerial_CDC_Interface, buf); +} + diff --git a/commands.h b/commands.h new file mode 100644 index 0000000..ffa6306 --- /dev/null +++ b/commands.h @@ -0,0 +1,16 @@ +#pragma once +void connectCTL(void); +void connectDUT(void); +void connectDataCTL(void); +void connectDataDUT(void); +void connectPowerCTL(void); +void connectPowerDUT(void); +void disconnect(void); +void disconnectData(void); +void disconnectPower(void); +void disconnectPowerCTL(void); +void disconnectPowerDUT(void); +void clearID(void); +void setID(void); +void status(void); +void debug(void); diff --git a/descriptors.c b/descriptors.c new file mode 100644 index 0000000..ae25bff --- /dev/null +++ b/descriptors.c @@ -0,0 +1,180 @@ +#include "descriptors.h" + + +const USB_Descriptor_Device_t PROGMEM 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 = 0x03EB, + .ProductID = 0x2044, + .ReleaseNumber = VERSION_BCD(0,0,1), + + .ManufacturerStrIndex = STRING_ID_Manufacturer, + .ProductStrIndex = STRING_ID_Product, + .SerialNumStrIndex = USE_INTERNAL_SERIAL, + + .NumberOfConfigurations = FIXED_NUM_CONFIGURATIONS +}; + +const USB_Descriptor_Configuration_t PROGMEM 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 = (USB_CONFIG_ATTR_RESERVED | USB_CONFIG_ATTR_SELFPOWERED), + + .MaxPowerConsumption = USB_CONFIG_POWER_MA(100) + }, + + .CDC_CCI_Interface = + { + .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface}, + + .InterfaceNumber = INTERFACE_ID_CDC_CCI, + .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 = CDC_DSUBTYPE_CSInterface_Header, + + .CDCSpecification = VERSION_BCD(1,1,0), + }, + + .CDC_Functional_ACM = + { + .Header = {.Size = sizeof(USB_CDC_Descriptor_FunctionalACM_t), .Type = CDC_DTYPE_CSInterface}, + .Subtype = CDC_DSUBTYPE_CSInterface_ACM, + + .Capabilities = 0x06, + }, + + .CDC_Functional_Union = + { + .Header = {.Size = sizeof(USB_CDC_Descriptor_FunctionalUnion_t), .Type = CDC_DTYPE_CSInterface}, + .Subtype = CDC_DSUBTYPE_CSInterface_Union, + + .MasterInterfaceNumber = INTERFACE_ID_CDC_CCI, + .SlaveInterfaceNumber = INTERFACE_ID_CDC_DCI, + }, + + .CDC_NotificationEndpoint = + { + .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint}, + + .EndpointAddress = CDC_NOTIFICATION_EPADDR, + .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 = INTERFACE_ID_CDC_DCI, + .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 = CDC_RX_EPADDR, + .Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA), + .EndpointSize = CDC_TXRX_EPSIZE, + .PollingIntervalMS = 0x05 + }, + + .CDC_DataInEndpoint = + { + .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint}, + + .EndpointAddress = CDC_TX_EPADDR, + .Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA), + .EndpointSize = CDC_TXRX_EPSIZE, + .PollingIntervalMS = 0x05 + } +}; + +const USB_Descriptor_String_t PROGMEM LanguageString = USB_STRING_DESCRIPTOR_ARRAY(LANGUAGE_ID_ENG); + +const USB_Descriptor_String_t PROGMEM ManufacturerString = USB_STRING_DESCRIPTOR(L"LUFA Library"); + +const USB_Descriptor_String_t PROGMEM ProductString = USB_STRING_DESCRIPTOR(L"LUFA CDC Demo"); + +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: + switch (DescriptorNumber) + { + case STRING_ID_Language: + Address = &LanguageString; + Size = pgm_read_byte(&LanguageString.Header.Size); + break; + case STRING_ID_Manufacturer: + Address = &ManufacturerString; + Size = pgm_read_byte(&ManufacturerString.Header.Size); + break; + case STRING_ID_Product: + Address = &ProductString; + Size = pgm_read_byte(&ProductString.Header.Size); + break; + } + + break; + } + + *DescriptorAddress = Address; + return Size; +} + diff --git a/descriptors.h b/descriptors.h new file mode 100644 index 0000000..545ef2d --- /dev/null +++ b/descriptors.h @@ -0,0 +1,110 @@ +/* + 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 + * + * Header file for Descriptors.c. + */ + +#ifndef _DESCRIPTORS_H_ +#define _DESCRIPTORS_H_ + + /* Includes: */ + #include + + #include + + /* Macros: */ + /** Endpoint address of the CDC device-to-host notification IN endpoint. */ + #define CDC_NOTIFICATION_EPADDR (ENDPOINT_DIR_IN | 2) + + /** Endpoint address of the CDC device-to-host data IN endpoint. */ + #define CDC_TX_EPADDR (ENDPOINT_DIR_IN | 3) + + /** Endpoint address of the CDC host-to-device data OUT endpoint. */ + #define CDC_RX_EPADDR (ENDPOINT_DIR_OUT | 4) + + /** Size in bytes of the CDC device-to-host notification IN endpoint. */ + #define CDC_NOTIFICATION_EPSIZE 8 + + /** Size in bytes of the CDC data IN and OUT endpoints. */ + #define CDC_TXRX_EPSIZE 16 + + /* 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; + + /** Enum for the device interface descriptor IDs within the device. Each interface descriptor + * should have a unique ID index associated with it, which can be used to refer to the + * interface from other descriptors. + */ + enum InterfaceDescriptors_t + { + INTERFACE_ID_CDC_CCI = 0, /**< CDC CCI interface descriptor ID */ + INTERFACE_ID_CDC_DCI = 1, /**< CDC DCI interface descriptor ID */ + }; + + /** Enum for the device string descriptor IDs within the device. Each string descriptor should + * have a unique ID index associated with it, which can be used to refer to the string from + * other descriptors. + */ + enum StringDescriptors_t + { + STRING_ID_Language = 0, /**< Supported Languages string descriptor ID (must be zero) */ + STRING_ID_Manufacturer = 1, /**< Manufacturer string ID */ + STRING_ID_Product = 2, /**< Product string ID */ + }; + + /* 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 + diff --git a/lufa b/lufa new file mode 160000 index 0000000..15cf780 --- /dev/null +++ b/lufa @@ -0,0 +1 @@ +Subproject commit 15cf7809c7d9e7a6e42f256309dd965b6c8cc20b diff --git a/main.c b/main.c new file mode 100644 index 0000000..a8a2f92 --- /dev/null +++ b/main.c @@ -0,0 +1,141 @@ +#include "main.h" +#include "board.h" +#include "commands.h" +#include "usb.h" + +static void GPIO_Init(); +static void HandleSerialByte(uint8_t); + +int main(void) +{ + GlobalInterruptEnable(); + SetupHardware(); + + /* Create a regular character stream for the interface so that it can be used with the stdio.h functions */ + CDC_Device_CreateStream(&VirtualSerial_CDC_Interface, &USBSerialStream); + + for (;;) + { + CheckInputs(); + + CDC_Device_USBTask(&VirtualSerial_CDC_Interface); + USB_USBTask(); + + /* Must read data from the host, or it will lock up while waiting for the device */ + int16_t data = CDC_Device_ReceiveByte(&VirtualSerial_CDC_Interface); + if (data >= 0) { + HandleSerialByte((uint8_t)(data & 0xFF)); + } + + CDC_Device_USBTask(&VirtualSerial_CDC_Interface); + USB_USBTask(); + } +} + +/** Configures the board hardware and chip peripherals for the demo's functionality. */ +void SetupHardware(void) +{ + /* Disable watchdog if enabled by bootloader/fuses */ + MCUSR &= ~(1 << WDRF); + wdt_disable(); + + /* Disable clock division */ + clock_prescale_set(clock_div_1); + + /* Hardware Initialization */ + GPIO_Init(); + USB_Init(); +} + +void GPIO_Init() { + // Port B: + // 0, 1, 2: Inputs Disconnect, Sel B, Sel A -> Pullup + // 7: SYS_LED + DDRB = 1<<7; + PINB |= (1 << 0) | (1 << 1) | (1 << 2); + // Port C: + // 2, 4, 5, 6, 7: C_SENSE, VBUS_CTRL_DET, HS, ~USBON, VBUS_DUT_DET + // DDRC = 0; + // Port D: + // 0, 1: IND_PORTA, EN_POW_CTRL + // 2, 3: IND_PORTB, EN_POW_DUT + // 4: ~OE + // 5: ~CTRL/DUT + // 6: UNRST + // 7: 5VMCU + DDRD = ~((1<<7) | (1<<6)); +} + +static int gotCommand = 0; +void CheckInputs(void) +{ + uint8_t portValue = (~PINB) & 7; + static int lV = 0; + if ((portValue == 0 || portValue == lV) && !gotCommand) { + return; + } + + lV = portValue; + gotCommand = 0; + + if (portValue & (1<<0)) { + disconnect(); + } else if (portValue & (1<<1)) { + connectDUT(); + } else if (portValue & (1<<2)) { + connectCTL(); + } +} + +static const struct { + char const *name; + void (*fun)(void); +} commands[] = { + { "C", connectCTL }, + { "PC", connectPowerCTL }, + { "DC", connectDataCTL }, + { "D", connectDUT }, + { "PD", connectPowerDUT }, + { "DD", connectDataDUT }, + { "dPC", disconnectPowerCTL }, + { "dPD", disconnectPowerDUT }, + { "dP", disconnectPower }, + { "dD", disconnectData }, + { "d", disconnect }, + { "I", setID }, + { "i", clearID }, + { "s", status }, + { "x", debug } +}; + +static void HandleCommand(char *cmd, int cmdLen) { + for (int i = 0; i < (sizeof commands) / (sizeof commands[0]); i++) { + if (!strncmp(commands[i].name, cmd, cmdLen)) { + gotCommand = 1; + commands[i].fun(); + return; + } + } + + fputs("Unknown command\r\n", &USBSerialStream); +} + +static void HandleSerialByte(uint8_t b) { + static char cmd[64]; + static int cmdLen = 0; + + if (b != '\r' && b != '\n') { + if (cmdLen < sizeof cmd - 1) { + cmd[cmdLen++] = b; + fputc(b, &USBSerialStream); + } + } else { + if (cmdLen > 0) { + fputs("\r\n", &USBSerialStream); + CDC_Device_Flush(&VirtualSerial_CDC_Interface); + cmd[cmdLen] = '\0'; + HandleCommand(cmd, cmdLen); + cmdLen = 0; + } + } +} diff --git a/main.h b/main.h new file mode 100644 index 0000000..87e3413 --- /dev/null +++ b/main.h @@ -0,0 +1,22 @@ +#pragma once +#include +#include +#include +#include +#include +#include + +#include "descriptors.h" + +#include +#include + +void SetupHardware(void); +void CheckInputs(void); + +void EVENT_USB_Device_Connect(void); +void EVENT_USB_Device_Disconnect(void); +void EVENT_USB_Device_ConfigurationChanged(void); +void EVENT_USB_Device_ControlRequest(void); + +extern USB_ClassInfo_CDC_Device_t VirtualSerial_CDC_Interface; diff --git a/makefile b/makefile new file mode 100644 index 0000000..13938dc --- /dev/null +++ b/makefile @@ -0,0 +1,42 @@ +# +# LUFA Library +# Copyright (C) Dean Camera, 2021. +# +# dean [at] fourwalledcubicle [dot] com +# www.lufa-lib.org +# +# -------------------------------------- +# LUFA Project Makefile. +# -------------------------------------- + +# Run "make help" for target help. + +MCU = atmega16u2 +ARCH = AVR8 +F_CPU = 16000000 +F_USB = $(F_CPU) +OPTIMIZATION = s +TARGET = BaitAndSwitch +SRC = main.c descriptors.c $(LUFA_SRC_USB) $(LUFA_SRC_USBCLASS) usb.c commands.c +LUFA_PATH = lufa/LUFA +CC_FLAGS = -DUSE_LUFA_CONFIG_HEADER -IConfig/ +LD_FLAGS = + +# Default target +all: + +# Include LUFA-specific DMBS extension modules +DMBS_LUFA_PATH ?= $(LUFA_PATH)/Build/LUFA +include $(DMBS_LUFA_PATH)/lufa-sources.mk +include $(DMBS_LUFA_PATH)/lufa-gcc.mk + +# Include common DMBS build system modules +DMBS_PATH ?= $(LUFA_PATH)/Build/DMBS/DMBS +include $(DMBS_PATH)/core.mk +include $(DMBS_PATH)/cppcheck.mk +include $(DMBS_PATH)/doxygen.mk +include $(DMBS_PATH)/dfu.mk +include $(DMBS_PATH)/gcc.mk +include $(DMBS_PATH)/hid.mk +include $(DMBS_PATH)/avrdude.mk +include $(DMBS_PATH)/atprogram.mk diff --git a/usb.c b/usb.c new file mode 100644 index 0000000..4a1a2ae --- /dev/null +++ b/usb.c @@ -0,0 +1,70 @@ +#include "main.h" +#include "board.h" + +int connected = 0; + +FILE USBSerialStream; + +USB_ClassInfo_CDC_Device_t VirtualSerial_CDC_Interface = + { + .Config = + { + .ControlInterfaceNumber = INTERFACE_ID_CDC_CCI, + .DataINEndpoint = + { + .Address = CDC_TX_EPADDR, + .Size = CDC_TXRX_EPSIZE, + .Banks = 1, + }, + .DataOUTEndpoint = + { + .Address = CDC_RX_EPADDR, + .Size = CDC_TXRX_EPSIZE, + .Banks = 1, + }, + .NotificationEndpoint = + { + .Address = CDC_NOTIFICATION_EPADDR, + .Size = CDC_NOTIFICATION_EPSIZE, + .Banks = 1, + }, + }, + }; + +void EVENT_USB_Device_Connect(void) +{ +} + +void EVENT_USB_Device_Disconnect(void) +{ + SysLedOff(); + connected = 0; +} + +void EVENT_USB_Device_ConfigurationChanged(void) +{ + bool ConfigSuccess = true; + + ConfigSuccess &= CDC_Device_ConfigureEndpoints(&VirtualSerial_CDC_Interface); + + if (ConfigSuccess) { + SysLedOn(); + } +} + +void EVENT_USB_Device_ControlRequest(void) +{ + CDC_Device_ProcessControlRequest(&VirtualSerial_CDC_Interface); +} + +void EVENT_CDC_Device_ControLineStateChanged(USB_ClassInfo_CDC_Device_t *const CDCInterfaceInfo) +{ + bool HostReady = (CDCInterfaceInfo->State.ControlLineStates.HostToDevice & CDC_CONTROL_LINE_OUT_DTR) != 0; + connected = HostReady; + if (connected) { + SysLedOn(); + } else { + SysLedOff(); + } +} + diff --git a/usb.h b/usb.h new file mode 100644 index 0000000..fa40a65 --- /dev/null +++ b/usb.h @@ -0,0 +1,3 @@ +#pragma once + +extern int connected;