You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
242 lines
6.3 KiB
242 lines
6.3 KiB
#include <util/delay.h>
|
|
#include <avr/io.h>
|
|
|
|
|
|
#include <LUFA/Drivers/USB/USB.h>
|
|
|
|
|
|
#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);
|
|
|
|
/* Pulse generation counters to keep track of the time remaining for each pulse type */
|
|
#define DATA_LED_PULSE_PERIOD 100
|
|
uint16_t DataLEDPulse = 0; // time remaining for Data LED pulse
|
|
|
|
uint16_t LLEDPulse;
|
|
void LEDPulse(void)
|
|
{
|
|
LLEDPulse++;
|
|
uint8_t p = LLEDPulse >> 8;
|
|
if (p > 127)
|
|
p = 254-p;
|
|
p += p;
|
|
if (((uint8_t)LLEDPulse) > p)
|
|
L_LED_OFF();
|
|
else
|
|
L_LED_ON();
|
|
}
|
|
|
|
|
|
|
|
void main () {
|
|
LED_SETUP();
|
|
|
|
/* Initialize USB Subsystem */
|
|
USB_Init();
|
|
|
|
/* Enable global interrupts so that the USB stack can function */
|
|
sei();
|
|
|
|
for(;;) {
|
|
CDC_Task();
|
|
USB_USBTask();
|
|
LEDPulse();
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
* 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;
|
|
|
|
/* 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();
|
|
}
|
|
|