working
This commit is contained in:
@@ -37,6 +37,49 @@
|
|||||||
|
|
||||||
#include "Descriptors.h"
|
#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 descriptor structure. This descriptor, located in SRAM memory, describes the overall
|
||||||
* device characteristics, including the supported USB version, control endpoint size and the
|
* 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
|
* number of device configurations. The descriptor is read out by the USB host when the enumeration
|
||||||
|
|||||||
@@ -39,6 +39,12 @@
|
|||||||
/* Includes: */
|
/* Includes: */
|
||||||
#include <LUFA/Drivers/USB/USB.h>
|
#include <LUFA/Drivers/USB/USB.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
extern USB_ClassInfo_CDC_Device_t VirtualSerial_CDC_Interface;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Macros: */
|
/* Macros: */
|
||||||
#if defined(__AVR_AT90USB1287__)
|
#if defined(__AVR_AT90USB1287__)
|
||||||
#define AVR_SIGNATURE_1 0x1E
|
#define AVR_SIGNATURE_1 0x1E
|
||||||
@@ -107,6 +113,8 @@
|
|||||||
/** Size of the CDC control interface notification endpoint bank, in bytes. */
|
/** Size of the CDC control interface notification endpoint bank, in bytes. */
|
||||||
#define CDC_NOTIFICATION_EPSIZE 8
|
#define CDC_NOTIFICATION_EPSIZE 8
|
||||||
|
|
||||||
|
#define INTERFACE_ID_CDC_CCI 0
|
||||||
|
|
||||||
/* Type Defines: */
|
/* Type Defines: */
|
||||||
/** Type define for the device configuration descriptor structure. This must be defined in the
|
/** 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
|
* application code, as the configuration descriptor contains several sub-descriptors which
|
||||||
|
|||||||
+92
-198
@@ -1,92 +1,19 @@
|
|||||||
#include <util/delay.h>
|
#include <util/delay.h>
|
||||||
#include <avr/io.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 LED_SETUP() DDRB |= (1<<0); DDRD |= (1<<5);
|
#define L_LED_ON() PORTD &= ~(1<<5)
|
||||||
#define L_LED_OFF() PORTD |= (1<<5)
|
#define L_LED_TOGGLE() PORTD ^= (1<<5)
|
||||||
#define L_LED_ON() PORTD &= ~(1<<5)
|
#define DATA_LED_OFF() PORTB |= (1<<0)
|
||||||
#define L_LED_TOGGLE() PORTD ^= (1<<5)
|
#define DATA_LED_ON() PORTB &= ~(1<<0)
|
||||||
#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 */
|
/* Pulse generation counters to keep track of the time remaining for each pulse type */
|
||||||
#define DATA_LED_PULSE_PERIOD 100
|
#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 () {
|
void main () {
|
||||||
LED_SETUP();
|
LED_SETUP();
|
||||||
@@ -117,126 +64,73 @@ void main () {
|
|||||||
/* Enable global interrupts so that the USB stack can function */
|
/* Enable global interrupts so that the USB stack can function */
|
||||||
sei();
|
sei();
|
||||||
|
|
||||||
for(;;) {
|
// keep the indicator on for a while
|
||||||
CDC_Task();
|
int light_cnt = 0;
|
||||||
USB_USBTask();
|
for (;;)
|
||||||
|
{
|
||||||
LEDPulse();
|
LEDPulse();
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
int16_t ch = UsbReceiveByte();
|
||||||
|
|
||||||
|
if (ch > 0) {
|
||||||
|
light_cnt = 10;
|
||||||
|
|
||||||
/*
|
if (ch == 'a') {
|
||||||
* some parts of this code are from LUFA.
|
UsbSendString_P(PSTR("OFF\r\n"));
|
||||||
*
|
} else if (ch == 'A') {
|
||||||
*
|
UsbSendString_P(PSTR("ON\r\n"));
|
||||||
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();
|
if (light_cnt > 0) {
|
||||||
|
light_cnt--;
|
||||||
|
} else {
|
||||||
|
DATA_LED_OFF();
|
||||||
|
}
|
||||||
|
|
||||||
|
CDC_Device_USBTask(&VirtualSerial_CDC_Interface);
|
||||||
|
USB_USBTask();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 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 Connection event. */
|
||||||
|
void EVENT_USB_Device_Connect(void)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 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