master
Ondřej Hruška 2 years ago
parent 4df793ecb2
commit 861ac9291b
  1. 43
      src/Descriptors.c
  2. 8
      src/Descriptors.h
  3. 272
      src/main.c

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

@ -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;
/*
* 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;
if (ch == 'a') {
UsbSendString_P(PSTR("OFF\r\n"));
} else if (ch == 'A') {
UsbSendString_P(PSTR("ON\r\n"));
}
}
/* Read in the bootloader command (first byte sent from host) */
uint8_t Command = FetchNextCommandByte();
if (light_cnt > 0) {
light_cnt--;
} else {
DATA_LED_OFF();
}
// COMMAND PROCESSING
if (Command == 'a')
{
WriteNextResponseByte('b');
WriteNextResponseByte('\r');
WriteNextResponseByte('\n');
CDC_Device_USBTask(&VirtualSerial_CDC_Interface);
USB_USBTask();
}
}
/* 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;
}
/** Event handler for the library USB Connection event. */
void EVENT_USB_Device_Connect(void)
{
//
}
Endpoint_ClearIN();
}
/** Event handler for the library USB Disconnection event. */
void EVENT_USB_Device_Disconnect(void)
{
//
}
/* Wait until the data has been sent to the host */
while (!(Endpoint_IsINReady()))
{
if (USB_DeviceState == DEVICE_STATE_Unattached)
return;
}
/** 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);
}
/* Select the OUT endpoint */
Endpoint_SelectEndpoint(CDC_RX_EPNUM);
/** Event handler for the library USB Control Request reception event. */
void EVENT_USB_Device_ControlRequest(void)
{
CDC_Device_ProcessControlRequest(&VirtualSerial_CDC_Interface);
}
/* Acknowledge the command from the host */
Endpoint_ClearOUT();
/** 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)
{
//
}

Loading…
Cancel
Save