working
This commit is contained in:
@@ -37,6 +37,49 @@
|
||||
|
||||
#include "Descriptors.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/** 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)
|
||||
|
||||
/** LUFA CDC Class driver interface configuration and state information. This structure is
|
||||
* passed to all CDC Class driver functions, so that multiple instances of the same class
|
||||
* within a device can be differentiated from one another.
|
||||
*/
|
||||
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,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
|
||||
/** 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
|
||||
|
||||
@@ -39,6 +39,12 @@
|
||||
/* Includes: */
|
||||
#include <LUFA/Drivers/USB/USB.h>
|
||||
|
||||
|
||||
|
||||
extern USB_ClassInfo_CDC_Device_t VirtualSerial_CDC_Interface;
|
||||
|
||||
|
||||
|
||||
/* Macros: */
|
||||
#if defined(__AVR_AT90USB1287__)
|
||||
#define AVR_SIGNATURE_1 0x1E
|
||||
@@ -107,6 +113,8 @@
|
||||
/** Size of the CDC control interface notification endpoint bank, in bytes. */
|
||||
#define CDC_NOTIFICATION_EPSIZE 8
|
||||
|
||||
#define INTERFACE_ID_CDC_CCI 0
|
||||
|
||||
/* 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
|
||||
|
||||
+90
-196
@@ -1,92 +1,19 @@
|
||||
#include <util/delay.h>
|
||||
#include <avr/io.h>
|
||||
#include <avr/pgmspace.h>
|
||||
|
||||
#include <LUFA/Drivers/USB/USB.h>
|
||||
|
||||
#include <LUFA/Drivers/USB/USB.h>
|
||||
#include "Descriptors.h"
|
||||
|
||||
// Pro Micro LEDs are: B0, D5
|
||||
|
||||
#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);
|
||||
#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)
|
||||
|
||||
/* Pulse generation counters to keep track of the time remaining for each pulse type */
|
||||
#define DATA_LED_PULSE_PERIOD 100
|
||||
@@ -107,6 +34,26 @@ void LEDPulse(void)
|
||||
}
|
||||
|
||||
|
||||
static int16_t UsbReceiveByte() {
|
||||
return CDC_Device_ReceiveByte(&VirtualSerial_CDC_Interface);
|
||||
}
|
||||
|
||||
static int8_t UsbSendData(const uint8_t* const bytes, uint16_t len) {
|
||||
return CDC_Device_SendData(&VirtualSerial_CDC_Interface, bytes, len);
|
||||
}
|
||||
|
||||
static int8_t UsbSendData_P(const uint8_t* const bytes, uint16_t len) {
|
||||
return CDC_Device_SendData_P(&VirtualSerial_CDC_Interface, bytes, len);
|
||||
}
|
||||
|
||||
static int8_t UsbSendString(const char* const str) {
|
||||
return CDC_Device_SendString(&VirtualSerial_CDC_Interface, str);
|
||||
}
|
||||
|
||||
static int8_t UsbSendString_P(const char* const str) {
|
||||
return CDC_Device_SendString_P(&VirtualSerial_CDC_Interface, str);
|
||||
}
|
||||
|
||||
|
||||
void main () {
|
||||
LED_SETUP();
|
||||
@@ -117,126 +64,73 @@ void main () {
|
||||
/* Enable global interrupts so that the USB stack can function */
|
||||
sei();
|
||||
|
||||
for(;;) {
|
||||
CDC_Task();
|
||||
USB_USBTask();
|
||||
// keep the indicator on for a while
|
||||
int light_cnt = 0;
|
||||
for (;;)
|
||||
{
|
||||
LEDPulse();
|
||||
|
||||
int16_t ch = UsbReceiveByte();
|
||||
|
||||
if (ch > 0) {
|
||||
light_cnt = 10;
|
||||
|
||||
if (ch == 'a') {
|
||||
UsbSendString_P(PSTR("OFF\r\n"));
|
||||
} else if (ch == 'A') {
|
||||
UsbSendString_P(PSTR("ON\r\n"));
|
||||
}
|
||||
}
|
||||
|
||||
if (light_cnt > 0) {
|
||||
light_cnt--;
|
||||
} else {
|
||||
DATA_LED_OFF();
|
||||
}
|
||||
|
||||
CDC_Device_USBTask(&VirtualSerial_CDC_Interface);
|
||||
USB_USBTask();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* 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)
|
||||
/** Event handler for the library USB Connection event. */
|
||||
void EVENT_USB_Device_Connect(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();
|
||||
//
|
||||
}
|
||||
|
||||
/** Event handler for the library USB Disconnection event. */
|
||||
void EVENT_USB_Device_Disconnect(void)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/** Event handler for the library USB Configuration Changed event. */
|
||||
void EVENT_USB_Device_ConfigurationChanged(void)
|
||||
{
|
||||
bool ConfigSuccess = true;
|
||||
ConfigSuccess &= CDC_Device_ConfigureEndpoints(&VirtualSerial_CDC_Interface);
|
||||
}
|
||||
|
||||
/** Event handler for the library USB Control Request reception event. */
|
||||
void EVENT_USB_Device_ControlRequest(void)
|
||||
{
|
||||
CDC_Device_ProcessControlRequest(&VirtualSerial_CDC_Interface);
|
||||
}
|
||||
|
||||
|
||||
/** Event handler for the CDC Class driver Line Encoding Changed event.
|
||||
*
|
||||
* \param[in] CDCInterfaceInfo Pointer to the CDC class interface configuration structure being referenced
|
||||
*/
|
||||
void EVENT_CDC_Device_LineEncodingChanged(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user