Skip to content
Permalink
Branch: master
Find file Copy path
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
218 lines (160 sloc) 5.78 KB
#include "VirtualSerial.h"
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/delay.h>
#define VAL_VSS 0b10001000
#define VAL_VCC 0b11101110
#define VAL_FLW 0b10001110
#define HEAD_MASK 0b11100000
#define HEAD_SYSCODE 0b00100000
#define HEAD_UNITCODE 0b01000000
#define HEAD_REPEAT 0b01100000
#define HEAD_SEND 0b11100000
#define DATAGRAM_SIZE 15
#define DATAGRAM_SYS_OFFSET 0
#define DATAGRAM_UC_OFFSET 5
#define DATAGRAM_SW_OFF 10
#define DATAGRAM_SW_ON 11
#define DATAGRAM_STOPBIT 12
#define LED_USB_STATUS (1<<PIN3)
#define LED_SEND_ACTIVITY (1<<PIN4)
#define LED_ON(led) PORTD |= led
#define LED_OFF(led) PORTD &= ~led
uint8_t datagram[DATAGRAM_SIZE];
uint8_t i = 0;
uint16_t repeat = 120;
uint8_t send = 1;
void receivePackage(uint8_t tmp) {
switch(tmp & HEAD_MASK) {
case HEAD_SYSCODE:
for(i = 0; i < 5; i++) {
datagram[DATAGRAM_SYS_OFFSET + i] = (tmp & (1<<i))? VAL_VSS : VAL_FLW;
}
break;
case HEAD_UNITCODE:
for(i = 0; i < 5; i++) {
datagram[DATAGRAM_UC_OFFSET + i] = (tmp & (1<<i))? VAL_VSS : VAL_FLW;
}
break;
case HEAD_REPEAT:
repeat = 5*(tmp & 0x1F);
break;
case HEAD_SEND:
if((tmp & 0b00011111) == 0) {
datagram[DATAGRAM_SW_OFF] = VAL_VSS;
datagram[DATAGRAM_SW_ON] = VAL_FLW;
} else {
datagram[DATAGRAM_SW_OFF] = VAL_FLW;
datagram[DATAGRAM_SW_ON] = VAL_VSS;
}
datagram[DATAGRAM_STOPBIT] = 0b10000000;
datagram[DATAGRAM_STOPBIT+1] = 0b00000000;
datagram[DATAGRAM_STOPBIT+2] = 0b00000000;
// datagram[DATAGRAM_STOPBIT+3] = 0b00000000;
send = 1;
break;
}
}
/** 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 = 0,
.DataINEndpointNumber = CDC_TX_EPNUM,
.DataINEndpointSize = CDC_TXRX_EPSIZE,
.DataINEndpointDoubleBank = false,
.DataOUTEndpointNumber = CDC_RX_EPNUM,
.DataOUTEndpointSize = CDC_TXRX_EPSIZE,
.DataOUTEndpointDoubleBank = false,
.NotificationEndpointNumber = CDC_NOTIFICATION_EPNUM,
.NotificationEndpointSize = CDC_NOTIFICATION_EPSIZE,
.NotificationEndpointDoubleBank = false,
},
};
uint8_t current_byte = 0;
uint8_t current_bit = 0;
uint8_t toggle = 0;
ISR(TIMER1_COMPA_vect){
if(send == 1) {
static uint8_t on = 0;
on = (datagram[current_byte] >> (7-current_bit)) & 1;
if(on) {
LED_ON(LED_SEND_ACTIVITY);
PORTD |= (1<<PIN1);
} else {
LED_OFF(LED_SEND_ACTIVITY);
PORTD &= ~(1<<PIN1);
}
current_bit++;
if(current_bit == 8) {
current_bit = 0;
if(current_byte < DATAGRAM_SIZE) {
current_byte++;
} else {
/* end now */
current_byte = 0;
if(repeat-- == 0) {
send = 0;
// set device off if nothing is to send
PORTD &= ~(1<<PIN1);
LED_OFF(LED_SEND_ACTIVITY);
/* ACK */
CDC_Device_SendByte(&VirtualSerial_CDC_Interface, 0x12);
}
}
}
}
}
static FILE USBSerialStream;
/** Main program entry point. This routine contains the overall program flow, including initial
* setup of all components and the main program loop.
*/
int main(void)
{
/* Disable watchdog if enabled by bootloader/fuses */
MCUSR &= ~(1 << WDRF);
wdt_disable();
/* Disable clock division */
clock_prescale_set(clock_div_1);
/* Hardware Initialization */
USB_Init();
DDRD |= (1<<PIN3) | (1 << PIN4) | (1<<PIN1);
PORTD &= ~(1<<PIN3);
// set sending device off
PORTD &= ~(1<<PIN1);
/* Interrupt setup */
TCCR1B = (1 << CS11) | (1 << WGM12);
OCR1A = 658;
TIMSK1 |= (1<<OCIE1A);
/* Create a regular character stream for the interface so that it can be used with the stdio.h functions */
CDC_Device_CreateStream(&VirtualSerial_CDC_Interface, &USBSerialStream);
sei();
for (;;) {
/* Must throw away unused bytes from the host, or it will lock up while waiting for the device */
int16_t byte = CDC_Device_ReceiveByte(&VirtualSerial_CDC_Interface);
if(byte > 0) {
receivePackage(byte);
}
CDC_Device_USBTask(&VirtualSerial_CDC_Interface);
USB_USBTask();
}
}
/** Event handler for the library USB Connection event. */
void EVENT_USB_Device_Connect(void) {
LED_ON(LED_USB_STATUS);
}
/** Event handler for the library USB Disconnection event. */
void EVENT_USB_Device_Disconnect(void) {
LED_OFF(LED_USB_STATUS);
}
/** 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);
}
You can’t perform that action at this time.