Initial commit

This commit is contained in:
Lynn Ochs 2023-08-16 21:07:52 +02:00
commit 22bb178687
14 changed files with 751 additions and 0 deletions

8
.gitignore vendored Normal file
View File

@ -0,0 +1,8 @@
BaitAndSwitch.bin
BaitAndSwitch.eep
BaitAndSwitch.elf
BaitAndSwitch.hex
BaitAndSwitch.lss
BaitAndSwitch.map
BaitAndSwitch.sym
obj

3
.gitmodules vendored Normal file
View File

@ -0,0 +1,3 @@
[submodule "lufa"]
path = lufa
url = https://github.com/abcminiuser/lufa.git

7
Config/LUFAConfig.h Normal file
View File

@ -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

34
board.h Normal file
View File

@ -0,0 +1,34 @@
#pragma once
#include <avr/io.h>
#include <stdio.h>
extern FILE USBSerialStream;
#define SET_FUN_N(NAME, PORT, PIN) inline static void NAME(void) { PORT |= (1<<PIN); }
#define CLR_FUN_N(NAME, PORT, PIN) inline static void NAME(void) { PORT &= ~(1<<PIN); }
#define GET_FUN_N(NAME, PORT, PIN) inline static int NAME(void) { return !!(PORT & (1<<PIN)); }
#define PIN_FUN_N(NAME, PORT_NAME, PIN_NUM) \
SET_FUN_N(NAME##On, PORT##PORT_NAME, PIN_NUM) \
CLR_FUN_N(NAME##Off, PORT##PORT_NAME, PIN_NUM) \
GET_FUN_N(NAME##Pin, PIN##PORT_NAME, PIN_NUM) \
GET_FUN_N(NAME##Port, PORT##PORT_NAME, PIN_NUM)
#define SET_FUN_I(NAME, PORT, PIN) inline static void NAME(void) { PORT &= ~(1<<PIN); }
#define CLR_FUN_I(NAME, PORT, PIN) inline static void NAME(void) { PORT |= (1<<PIN); }
#define GET_FUN_I(NAME, PORT, PIN) inline static int NAME(void) { return !(PORT & (1<<PIN)); }
#define PIN_FUN_I(NAME, PORT_NAME, PIN_NUM) \
SET_FUN_I(NAME##On, PORT##PORT_NAME, PIN_NUM) \
CLR_FUN_I(NAME##Off, PORT##PORT_NAME, PIN_NUM) \
GET_FUN_I(NAME##Pin, PIN##PORT_NAME, PIN_NUM) \
GET_FUN_I(NAME##Port, PORT##PORT_NAME, PIN_NUM)
PIN_FUN_N(SysLed, B, 7)
PIN_FUN_N(PortAInd, D, 0)
PIN_FUN_N(PortBInd, D, 2)
PIN_FUN_N(PortAPow, D, 1)
PIN_FUN_N(PortBPow, D, 3)
PIN_FUN_I(OutEn, D, 4)
PIN_FUN_I(CtrlData, D, 5)
PIN_FUN_N(DutData, D, 5)

114
commands.c Normal file
View File

@ -0,0 +1,114 @@
#include "board.h"
#include "commands.h"
#include "usb.h"
#include "main.h"
#include <LUFA/Drivers/USB/USB.h>
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);
}

16
commands.h Normal file
View File

@ -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);

180
descriptors.c Normal file
View File

@ -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;
}

110
descriptors.h Normal file
View File

@ -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 <avr/pgmspace.h>
#include <LUFA/Drivers/USB/USB.h>
/* 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

1
lufa Submodule

@ -0,0 +1 @@
Subproject commit 15cf7809c7d9e7a6e42f256309dd965b6c8cc20b

141
main.c Normal file
View File

@ -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;
}
}
}

22
main.h Normal file
View File

@ -0,0 +1,22 @@
#pragma once
#include <avr/io.h>
#include <avr/wdt.h>
#include <avr/power.h>
#include <avr/interrupt.h>
#include <string.h>
#include <stdio.h>
#include "descriptors.h"
#include <LUFA/Drivers/USB/USB.h>
#include <LUFA/Platform/Platform.h>
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;

42
makefile Normal file
View File

@ -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

70
usb.c Normal file
View File

@ -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();
}
}

3
usb.h Normal file
View File

@ -0,0 +1,3 @@
#pragma once
extern int connected;