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.
183 lines
4.3 KiB
183 lines
4.3 KiB
#include <util/delay.h>
|
|
#include <avr/io.h>
|
|
#include <avr/pgmspace.h>
|
|
|
|
#include <LUFA/Drivers/USB/USB.h>
|
|
|
|
#include "Descriptors.h"
|
|
|
|
// Pro Micro LEDs are: B0, D5
|
|
|
|
#define LED_SETUP() DDRB |= (1<<0); DDRD |= (1<<5);
|
|
#define L_LED_OFF() PORTD |= (1<<5)
|
|
#define L_LED_ON() PORTD &= ~(1<<5)
|
|
#define DATA_LED_OFF() PORTB |= (1<<0)
|
|
#define DATA_LED_ON() PORTB &= ~(1<<0)
|
|
|
|
static uint16_t DataBlinkCounter = 0;
|
|
static uint32_t HeartbeatCounter = 498000; // make it blink immediately
|
|
|
|
void LEDPulse(void)
|
|
{
|
|
HeartbeatCounter++;
|
|
if (HeartbeatCounter > 498000) {
|
|
L_LED_ON();
|
|
}
|
|
if (HeartbeatCounter > 500000) {
|
|
L_LED_OFF();
|
|
HeartbeatCounter = 0;
|
|
}
|
|
}
|
|
|
|
|
|
static int16_t UsbReceiveByte() {
|
|
return CDC_Device_ReceiveByte(&VirtualSerial_CDC_Interface);
|
|
}
|
|
|
|
static int8_t UsbSendByte(uint8_t byte) {
|
|
return CDC_Device_SendByte(&VirtualSerial_CDC_Interface, byte);
|
|
}
|
|
|
|
|
|
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();
|
|
|
|
/* Initialize USB Subsystem */
|
|
USB_Init();
|
|
|
|
/* Enable global interrupts so that the USB stack can function */
|
|
sei();
|
|
|
|
#define PINS \
|
|
X(D, 3, 'A') \
|
|
X(D, 2, 'B') \
|
|
X(D, 1, 'C') \
|
|
X(D, 0, 'D') \
|
|
X(D, 4, 'E') \
|
|
X(C, 6, 'F') \
|
|
X(D, 7, 'G') \
|
|
X(E, 6, 'H') \
|
|
X(B, 4, 'I') \
|
|
X(B, 5, 'J') \
|
|
X(B, 6, 'K') \
|
|
X(B, 2, 'L') \
|
|
X(B, 3, 'M') \
|
|
X(B, 1, 'N') \
|
|
X(F, 7, 'O') \
|
|
X(F, 6, 'P') \
|
|
X(F, 5, 'Q') \
|
|
X(F, 4, 'R')
|
|
|
|
#define X(port, pin, ch) DDR##port |= _BV(pin);
|
|
PINS
|
|
#undef X
|
|
|
|
for (;;)
|
|
{
|
|
LEDPulse();
|
|
|
|
int16_t readch = UsbReceiveByte();
|
|
|
|
if (readch > 0 && readch != '\r' && readch != '\n') {
|
|
DATA_LED_ON();
|
|
DataBlinkCounter = 1000; // this makes a pretty short blink
|
|
bool valid = 0;
|
|
|
|
if (readch == '0') {
|
|
valid = 1;
|
|
#define X(port, pin, ch) \
|
|
PORT##port &= ~_BV(pin);
|
|
PINS
|
|
#undef X
|
|
} else if (readch == '1') {
|
|
valid = 1;
|
|
#define X(port, pin, ch) \
|
|
PORT##port |= _BV(pin);
|
|
PINS
|
|
#undef X
|
|
} else
|
|
// xmacro magic
|
|
#define X(port, pin, ch) \
|
|
if (readch == ch) { \
|
|
PORT##port |= _BV(pin); \
|
|
valid = 1; \
|
|
} else if (readch == (ch + 32)) { /* lowercase */ \
|
|
PORT##port &= ~_BV(pin); \
|
|
valid = 1; \
|
|
} else
|
|
PINS
|
|
/* last else */ {}
|
|
#undef X
|
|
|
|
if (valid) {
|
|
UsbSendByte(readch);
|
|
} else {
|
|
UsbSendByte('?');
|
|
}
|
|
}
|
|
|
|
if (DataBlinkCounter > 0) {
|
|
DataBlinkCounter--;
|
|
} else {
|
|
DATA_LED_OFF();
|
|
}
|
|
|
|
CDC_Device_USBTask(&VirtualSerial_CDC_Interface);
|
|
USB_USBTask();
|
|
}
|
|
}
|
|
|
|
/** 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)
|
|
{
|
|
//
|
|
}
|
|
|
|
|
|
|
|
|