main.c file reverted.

This commit is contained in:
klaute 2016-08-30 19:00:12 +02:00
parent f2837f8bfe
commit 550962d43a

View file

@ -1,21 +1,13 @@
/**
* description: Modified LUFA example to get two virtual serial USB devices.
* author: Kai Lauterbach
* date: 08/2016
* version: v0.1
* license: GPLv3
*/
/* /*
LUFA Library LUFA Library
Copyright (C) Dean Camera, 2016. Copyright (C) Dean Camera, 2015.
dean [at] fourwalledcubicle [dot] com dean [at] fourwalledcubicle [dot] com
www.lufa-lib.org www.lufa-lib.org
*/ */
/* /*
Copyright 2016 Dean Camera (dean [at] fourwalledcubicle [dot] com) Copyright 2015 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted software and its documentation for any purpose is hereby granted
@ -38,467 +30,357 @@
/** \file /** \file
* *
* Main source file for the project - based on the Mouse and VirtualSerial lufa demo. * Main source file for the iUSB2SerialMux demo. This file contains the main tasks of the demo and
* This file contains the main tasks of the demo and is responsible for the initial * is responsible for the initial application hardware configuration.
* application hardware configuration.
*/ */
#include "main.h" #include "main.h"
//********************************************************************************// /**************************************************************************************/
FIFO_t agent_fifo; uint32_t EEMEM eep_baudrate;
FIFO_t seq_mod_fifo;
FIFO_t seq_val_fifo;
uint8_t seq_delay = 0; uint32_t baudrate = 115200; // replacement for the UART_BAUDRATE definition
volatile uint16_t time_measure_cnt = 0; /**************************************************************************************/
volatile uint16_t keystroke_delay_time_measure_cnt_old = 0;
volatile uint16_t seq_delay_time_measure_cnt_old = 0;
//********************************************************************************// /** Contains the current baud rate and other settings of the first virtual serial port. While this demo does not use
* the physical USART and thus does not use these settings, they must still be retained and returned to the host
/** Buffer to hold the previously generated Keyboard HID report, for comparison purposes inside the HID class driver. */ * upon request or the host will assume the device is non-functional.
static uint8_t PrevKeyboardHIDReportBuffer[sizeof(USB_KeyboardReport_Data_t)]; *
* These values are set by the host via a class-specific request, however they are not required to be used accurately.
//********************************************************************************// * It is possible to completely ignore these value or use other settings as the host is completely unaware of the physical
* serial link characteristics and instead sends and receives data in endpoint streams.
/** LUFA HID Class driver interface configuration and state information. This structure is
* passed to all HID Class driver functions, so that multiple instances of the same class
* within a device can be differentiated from one another. This is for the keyboard HID
* interface within the device.
*/ */
USB_ClassInfo_HID_Device_t Keyboard_HID_Interface = static CDC_LineEncoding_t LineEncoding1 = { .BaudRateBPS = 0,
{ .CharFormat = CDC_LINEENCODING_OneStopBit,
.Config = .ParityType = CDC_PARITY_None,
{ .DataBits = 8 };
.InterfaceNumber = INTERFACE_ID_Keyboard,
.ReportINEndpoint =
{
.Address = KEYBOARD_IN_EPADDR,
.Size = KEYBOARD_EPSIZE,
.Banks = 1,
},
.PrevReportINBuffer = PrevKeyboardHIDReportBuffer,
.PrevReportINBufferSize = sizeof(PrevKeyboardHIDReportBuffer),
},
};
/** LUFA CDC Class driver interface configuration and state information. This structure is /** Contains the current baud rate and other settings of the second virtual serial port. While this demo does not use
* passed to all CDC Class driver functions, so that multiple instances of the same class * the physical USART and thus does not use these settings, they must still be retained and returned to the host
* within a device can be differentiated from one another. * upon request or the host will assume the device is non-functional.
*
* These values are set by the host via a class-specific request, however they are not required to be used accurately.
* It is possible to completely ignore these value or use other settings as the host is completely unaware of the physical
* serial link characteristics and instead sends and receives data in endpoint streams.
*/ */
USB_ClassInfo_CDC_Device_t VirtualSerial_CDC_Interface = static CDC_LineEncoding_t LineEncoding2 = { .BaudRateBPS = 0,
{ .CharFormat = CDC_LINEENCODING_OneStopBit,
.Config = .ParityType = CDC_PARITY_None,
{ .DataBits = 8 };
.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,
},
},
};
/** Standard file stream for the CDC interface when set up, so that the virtual
* CDC COM port can be used like any regular character stream in the C APIs.
*/
static FILE USBSerialStream;
//********************************************************************************// /** Main program entry point. This routine configures the hardware required by the application, then
* enters a loop to run the application tasks in sequence.
/** 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) int main(void)
{ {
// USB/LUFA init
SetupHardware(); SetupHardware();
// init the timer for time measurements // initialize the command interpreter
timer_init();
// LED matrix init
lm_init();
// KEY matrix init
km_init();
// read the key configuration table from EEPROM
ch_readConfig();
// init the serial communication command controller
cc_init(); cc_init();
FIFO_init( agent_fifo); SET_ERR_MASK(ERRMASK_USB_NOTREADY);
FIFO_init(seq_mod_fifo);
FIFO_init(seq_val_fifo);
// 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);
SET_GLOB_USB_STATUS(STATUSMASK_USB_NOTREADY);
GlobalInterruptEnable(); GlobalInterruptEnable();
for (;;) for (;;)
{ {
SendVirtualSerialData(); CDC1_Task();
CDC2_Task();
ProcessVirtualSerialData();
CDC_Device_USBTask(&VirtualSerial_CDC_Interface);
HID_Device_USBTask(&Keyboard_HID_Interface);
USB_USBTask(); USB_USBTask();
static uint8_t delay = 0; //uart_putc('1');
if (delay > 50)
{
delay = 0;
lm_show();
}
delay++;
} }
} }
//********************************************************************************// /** Configures the board hardware and chip peripherals for the demo's functionality. */
void SetupHardware(void)
void timer_init()
{
// configure TIMER0 to count using a specified frequency the TCNT0 variable to generate
// a overflow interrupt
TCCR0A = 0x02; // WGM1 = 1; WGM0 = 0 => CTC-mode
TCCR0B = 0x03; // prescaler = 64; WGM2 = 0 => 16MHz * 256 / 64 = ~ 1mz per Overflow Interrupt
TIMSK0 = 0x01; // Overflow Interrupt Enable
sei();
}
ISR(TCC0_OVF_vect)
{
if (time_measure_cnt >= 65534)
{
// reset all the counter values to prevent unpredictable behaviour
time_measure_cnt = 0;
seq_delay_time_measure_cnt_old = 0;
keystroke_delay_time_measure_cnt_old = 0;
}
time_measure_cnt++;
}
//********************************************************************************//
/** Configures the board hardware and chip peripherals for the demo's functionality.
*/
void SetupHardware()
{ {
#if (ARCH == ARCH_AVR8) #if (ARCH == ARCH_AVR8)
// Disable watchdog if enabled by bootloader/fuses /* Disable watchdog if enabled by bootloader/fuses */
MCUSR &= ~(1 << WDRF); MCUSR &= ~(1 << WDRF);
wdt_disable(); wdt_disable();
// Disable clock division */ /* Disable clock division */
clock_prescale_set(clock_div_1); clock_prescale_set(clock_div_1);
#elif (ARCH == ARCH_XMEGA) #elif (ARCH == ARCH_XMEGA)
// Start the PLL to multiply the 2MHz RC oscillator to 32MHz and switch the CPU /* Start the PLL to multiply the 2MHz RC oscillator to 32MHz and switch the CPU core to run from it */
// core to run from it
XMEGACLK_StartPLL(CLOCK_SRC_INT_RC2MHZ, 2000000, F_CPU); XMEGACLK_StartPLL(CLOCK_SRC_INT_RC2MHZ, 2000000, F_CPU);
XMEGACLK_SetCPUClockSource(CLOCK_SRC_PLL); XMEGACLK_SetCPUClockSource(CLOCK_SRC_PLL);
// Start the 32MHz internal RC oscillator and start the DFLL to increase it to /* Start the 32MHz internal RC oscillator and start the DFLL to increase it to 48MHz using the USB SOF as a reference */
// 48MHz using the USB SOF as a reference
XMEGACLK_StartInternalOscillator(CLOCK_SRC_INT_RC32MHZ); XMEGACLK_StartInternalOscillator(CLOCK_SRC_INT_RC32MHZ);
XMEGACLK_StartDFLL(CLOCK_SRC_INT_RC32MHZ, DFLL_REF_INT_USBSOF, F_USB); XMEGACLK_StartDFLL(CLOCK_SRC_INT_RC32MHZ, DFLL_REF_INT_USBSOF, F_USB);
PMIC.CTRL = PMIC_LOLVLEN_bm | PMIC_MEDLVLEN_bm | PMIC_HILVLEN_bm; PMIC.CTRL = PMIC_LOLVLEN_bm | PMIC_MEDLVLEN_bm | PMIC_HILVLEN_bm;
#endif #endif
// Hardware Initialization */ // set the three MUX control lines to output
DDRB |= (1 << PIN4) | (1 << PIN5) | (1 << PIN6);
// set every pin to low
EN_MUX_LINE0;
DDRB |= (1 << PIN0) | (1 << PIN1);
LED0_OFF;
LED1_OFF;
/* UART Hardware Initialization */
eeprom_busy_wait();
baudrate = eeprom_read_dword(&eep_baudrate);
if (baudrate == 0xffffffff)
{
eeprom_busy_wait();
baudrate = 115200;
eeprom_write_dword(&eep_baudrate, baudrate);
}
uart_init( UART_BAUD_SELECT(baudrate, F_CPU) );
sei();
/* USB Hardware Initialization */
USB_Init(); USB_Init();
} }
//********************************************************************************// /** Event handler for the USB_Connect event. This indicates that the device is enumerating via the status LEDs and
* starts the library USB task to begin the enumeration and USB management process.
void ProcessVirtualSerialData()
{
// process the read data from Host here, if there is data to read
int16_t ReceivedBytes = CDC_Device_BytesReceived(&VirtualSerial_CDC_Interface);
if (ReceivedBytes > 0)
{
for (uint16_t i = 0; i < ReceivedBytes; i++)
{
int16_t ReceivedByte = CDC_Device_ReceiveByte(&VirtualSerial_CDC_Interface);
// call the command controller - command processor
cc_processData((uint8_t)ReceivedByte);
}
}
}
//********************************************************************************//
void SendVirtualSerialData()
{
char* ReportString = NULL;
// send the next id from the agent FIFO
if (FIFO_available(agent_fifo))
{
uint8_t id = FIFO_pop(agent_fifo);
ReportString = " ";
sprintf(ReportString, "%c%c%c%c%c%c", MSG_SOM1, MSG_SOM2,
MSG_TYPE_AGENTID, id,
MSG_EOM1, MSG_EOM2);
}
if ((ReportString != NULL))
{
// Write the string to the virtual COM port via the created character stream
USB_serialStreamWriteC(ReportString, 6);
}
}
//********************************************************************************//
/** HID class driver callback function for the creation of HID reports to the host.
*
* \param[in] HIDInterfaceInfo Pointer to the HID class interface configuration structure being referenced
* \param[in,out] ReportID Report ID requested by the host if non-zero, otherwise callback should set to the generated report ID
* \param[in] ReportType Type of the report to create, either HID_REPORT_ITEM_In or HID_REPORT_ITEM_Feature
* \param[out] ReportData Pointer to a buffer where the created report should be stored
* \param[out] ReportSize Number of bytes written in the report (or zero if no report is to be sent)
*
* \return Boolean \c true to force the sending of the report, \c false to let the library determine if it needs to be sent
*/ */
bool CALLBACK_HID_Device_CreateHIDReport(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo,
uint8_t* const ReportID,
const uint8_t ReportType,
void* ReportData,
uint16_t* const ReportSize)
{
// Determine which interface must have its report generated */
if (HIDInterfaceInfo == &Keyboard_HID_Interface)
{
USB_KeyboardReport_Data_t* KeyboardReport = (USB_KeyboardReport_Data_t*)ReportData;
// update the key matrix values
km_updateKeyStates();
// prepare the new sequence related to the pressed key
for (uint8_t k = 0; k < LM_LED_CNT; k++)
{
if (km_getKeyState(k) == KEY_STATE_GO_DOWN)
{
FIFO_push(agent_fifo, k);
for (uint8_t s = 0; s < EEP_KEY_CNT; s++)
{
// ignore a mod/value combination of 0xff 0xff
// just add the sequence to a "sequence execution FIFO" in case that it
// is not an agent call
// prevent multiple calls
// TODO manage multikey (simultanous pressed) shortcuts here
if (key_config[k][s][0] == 0xff && key_config[k][s][1] == 0xff)
{
s = EEP_KEY_CNT; // abort the loop, no more data found
} else {
FIFO_push(seq_mod_fifo, key_config[k][s][0]);
FIFO_push(seq_val_fifo, key_config[k][s][1]);
}
}
}
}
// TODO maybe we shall do ab bit more precise time measurement
if (seq_delay > 0 && time_measure_cnt > seq_delay_time_measure_cnt_old)
{
seq_delay--;
seq_delay_time_measure_cnt_old = time_measure_cnt;
}
if (keystroke_delay_cnt > 0 && time_measure_cnt > keystroke_delay_time_measure_cnt_old)
{
// TODO test if NN seconds are gone
keystroke_delay_cnt--;
keystroke_delay_time_measure_cnt_old = time_measure_cnt;
}
// execute the sequence execution FIFO content
if (FIFO_available(seq_mod_fifo) && FIFO_available(seq_val_fifo) &&
seq_delay == 0 && keystroke_delay_cnt == 0)
{
uint8_t mod = FIFO_pop(seq_mod_fifo);
uint8_t val = FIFO_pop(seq_val_fifo);
// reset the keystroke delay
keystroke_delay_cnt = keystroke_delay;
// process the data
if ((mod & KEY_MOD_DELAY) != 0)
{
// start the delay
seq_delay = val;
} else {
// TODO be aware of the os_type variable
if ((mod & KEY_MOD_FN) != 0)
KeyboardReport->Modifier += HID_KEYBOARD_MODIFIER_RIGHTSHIFT; // TODO fix the modifier
if ((mod & KEY_MOD_SHIFT) != 0)
KeyboardReport->Modifier += HID_KEYBOARD_MODIFIER_LEFTSHIFT;
if ((mod & KEY_MOD_CTRL) != 0)
KeyboardReport->Modifier += HID_KEYBOARD_MODIFIER_LEFTCTRL;
if ((mod & KEY_MOD_ALT) != 0)
KeyboardReport->Modifier += HID_KEYBOARD_MODIFIER_LEFTALT;
if ((mod & KEY_MOD_ALTGR) != 0)
KeyboardReport->Modifier += HID_KEYBOARD_MODIFIER_RIGHTALT;
if ((mod & KEY_MOD_SUPER) != 0)
KeyboardReport->Modifier += HID_KEYBOARD_MODIFIER_LEFTGUI;
// possible values: http://www.fourwalledcubicle.com/files/LUFA/Doc/120219/html/group___group___u_s_b_class_h_i_d_common.html
KeyboardReport->KeyCode[0] = val; // TODO one key at a time, up to 6 is supported: http://www.fourwalledcubicle.com/files/LUFA/Doc/120219/html/struct_u_s_b___keyboard_report___data__t.html#a1c24d97011685d58ab05e2f65d7b2c1b
}
}
// Some debug and test code
for (uint8_t i = 0; i < LM_LED_CNT; i++)
{
if (km_getKeyState(i) == KEY_STATE_GO_DOWN)
lm_ledOn(i);
if (km_getKeyState(i) == KEY_STATE_GO_UP)
lm_ledOff(i);
}
*ReportSize = sizeof(USB_KeyboardReport_Data_t);
}
return false;
}
//********************************************************************************//
/** HID class driver callback function for the processing of HID reports from the host.
*
* \param[in] HIDInterfaceInfo Pointer to the HID class interface configuration structure being referenced
* \param[in] ReportID Report ID of the received report from the host
* \param[in] ReportType The type of report that the host has sent, either HID_REPORT_ITEM_Out or HID_REPORT_ITEM_Feature
* \param[in] ReportData Pointer to a buffer where the received report has been stored
* \param[in] ReportSize Size in bytes of the received HID report
*/
void CALLBACK_HID_Device_ProcessHIDReport(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo,
const uint8_t ReportID,
const uint8_t ReportType,
const void* ReportData,
const uint16_t ReportSize)
{
if (HIDInterfaceInfo == &Keyboard_HID_Interface)
{
uint8_t* LEDReport = (uint8_t*)ReportData;
/*
// TODO process the Keyboard LED status information
if (*LEDReport & HID_KEYBOARD_LED_NUMLOCK)
if (*LEDReport & HID_KEYBOARD_LED_CAPSLOCK)
if (*LEDReport & HID_KEYBOARD_LED_SCROLLLOCK)
*/
}
}
//********************************************************************************//
/** CDC class driver callback function the processing of changes to the virtual
* control lines sent from the host..
*
* \param[in] CDCInterfaceInfo Pointer to the CDC class interface configuration structure being referenced
*/
void EVENT_CDC_Device_ControLineStateChanged(USB_ClassInfo_CDC_Device_t *const CDCInterfaceInfo)
{
// You can get changes to the virtual CDC lines in this callback; a common
// use-case is to use the Data Terminal Ready (DTR) flag to enable and
// disable CDC communications in your application when set to avoid the
// application blocking while waiting for a host to become ready and read
// in the pending data from the USB endpoints.
bool HostReady = (CDCInterfaceInfo->State.ControlLineStates.HostToDevice & CDC_CONTROL_LINE_OUT_DTR) != 0;
}
//********************************************************************************//
/** Event handler for the library USB Connection event. */
void EVENT_USB_Device_Connect(void) void EVENT_USB_Device_Connect(void)
{ {
SET_GLOB_USB_STATUS(STATUSMASK_USB_ENUMERATING); /* Indicate USB enumerating */
SET_ERR_MASK(ERRMASK_USB_ENUMERATING);
} }
/** Event handler for the library USB Disconnection event. */ /** Event handler for the USB_Disconnect event. This indicates that the device is no longer connected to a host via
* the status LEDs and stops the USB management and CDC management tasks.
*/
void EVENT_USB_Device_Disconnect(void) void EVENT_USB_Device_Disconnect(void)
{ {
SET_GLOB_USB_STATUS(STATUSMASK_USB_NOTREADY); /* Indicate USB not ready */
SET_ERR_MASK(ERRMASK_USB_NOTREADY);
} }
/** Event handler for the library USB Configuration Changed event. */ /** Event handler for the USB_ConfigurationChanged event. This is fired when the host set the current configuration
* of the USB device after enumeration - the device endpoints are configured and the CDC management tasks are started.
*/
void EVENT_USB_Device_ConfigurationChanged(void) void EVENT_USB_Device_ConfigurationChanged(void)
{ {
bool ConfigSuccess = true; bool ConfigSuccess = true;
ConfigSuccess &= HID_Device_ConfigureEndpoints(&Keyboard_HID_Interface); /* Setup first CDC Interface's Endpoints */
ConfigSuccess &= CDC_Device_ConfigureEndpoints(&VirtualSerial_CDC_Interface); ConfigSuccess &= Endpoint_ConfigureEndpoint(CDC1_TX_EPADDR, EP_TYPE_BULK, CDC_TXRX_EPSIZE, 1);
ConfigSuccess &= Endpoint_ConfigureEndpoint(CDC1_RX_EPADDR, EP_TYPE_BULK, CDC_TXRX_EPSIZE, 1);
ConfigSuccess &= Endpoint_ConfigureEndpoint(CDC1_NOTIFICATION_EPADDR, EP_TYPE_INTERRUPT, CDC_NOTIFICATION_EPSIZE, 1);
USB_Device_EnableSOFEvents(); /* Setup second CDC Interface's Endpoints */
ConfigSuccess &= Endpoint_ConfigureEndpoint(CDC2_TX_EPADDR, EP_TYPE_BULK, CDC_TXRX_EPSIZE, 1);
ConfigSuccess &= Endpoint_ConfigureEndpoint(CDC2_RX_EPADDR, EP_TYPE_BULK, CDC_TXRX_EPSIZE, 1);
ConfigSuccess &= Endpoint_ConfigureEndpoint(CDC2_NOTIFICATION_EPADDR, EP_TYPE_INTERRUPT, CDC_NOTIFICATION_EPSIZE, 1);
SET_GLOB_USB_STATUS(ConfigSuccess ? STATUSMASK_USB_READY : STATUSMASK_USB_ERROR); /* Reset line encoding baud rates so that the host knows to send new values */
LineEncoding1.BaudRateBPS = 0;
LineEncoding2.BaudRateBPS = 0;
/* Indicate endpoint configuration success or failure */
SET_ERR_MASK(ConfigSuccess ? ERRMASK_USB_READY : ERRMASK_USB_ERROR);
} }
/** Event handler for the library USB Control Request reception event. */ /** Event handler for the USB_ControlRequest event. This is used to catch and process control requests sent to
* the device from the USB host before passing along unhandled control requests to the library for processing
* internally.
*/
void EVENT_USB_Device_ControlRequest(void) void EVENT_USB_Device_ControlRequest(void)
{ {
HID_Device_ProcessControlRequest(&Keyboard_HID_Interface); /* Determine which interface's Line Coding data is being set from the wIndex parameter */
CDC_Device_ProcessControlRequest(&VirtualSerial_CDC_Interface); void* LineEncodingData = (USB_ControlRequest.wIndex == 0) ? &LineEncoding1 : &LineEncoding2;
}
/** Event handler for the USB device Start Of Frame event. */ /* Process CDC specific control requests */
void EVENT_USB_Device_StartOfFrame(void) switch (USB_ControlRequest.bRequest)
{
HID_Device_MillisecondElapsed(&Keyboard_HID_Interface);
}
//********************************************************************************//
void USB_serialStreamWriteC(char* msg, uint16_t len)
{
for (uint8_t i = 0; i < len; i++)
{ {
fputc(msg[i], &USBSerialStream); case CDC_REQ_GetLineEncoding:
if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
{
Endpoint_ClearSETUP();
/* Write the line coding data to the control endpoint */
Endpoint_Write_Control_Stream_LE(LineEncodingData, sizeof(CDC_LineEncoding_t));
Endpoint_ClearOUT();
}
break;
case CDC_REQ_SetLineEncoding:
if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
{
Endpoint_ClearSETUP();
/* Read the line coding data in from the host into the global struct */
Endpoint_Read_Control_Stream_LE(LineEncodingData, sizeof(CDC_LineEncoding_t));
Endpoint_ClearIN();
}
break;
case CDC_REQ_SetControlLineState:
if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
{
Endpoint_ClearSETUP();
Endpoint_ClearStatusStage();
}
break;
} }
} }
void USB_serialStreamWrite(char* msg) /** Function to manage CDC data transmission and reception to and from the host for the first CDC interface,
* which sends answers or response data to the host.
*/
void CDC1_Task(void)
{ {
fputs(msg, &USBSerialStream); /* Device must be connected and configured for the task to run */
if (USB_DeviceState != DEVICE_STATE_Configured)
return;
//===========================================================================
/* Select the Serial Rx Endpoint */
Endpoint_SelectEndpoint(CDC1_RX_EPADDR);
if (Endpoint_IsOUTReceived())
{
/* Create a temp buffer big enough to hold the incoming endpoint packet */
uint8_t Buffer[Endpoint_BytesInEndpoint()];
/* Remember how large the incoming packet is */
uint16_t DataLength = Endpoint_BytesInEndpoint();
/* Read in the incoming packet into the buffer */
Endpoint_Read_Stream_LE(&Buffer, DataLength, NULL);
/* Finalize the stream transfer to send the last packet */
Endpoint_ClearOUT();
for (uint16_t i = 0; i < DataLength; i++)
{
// process the received data and descide to do an action
LED0_ON;
cc_processData(Buffer[i]);
LED0_OFF;
}
}
} }
//********************************************************************************// void USB_serialStreamWriteC(char *data, uint16_t len)
{
//===========================================================================
/* Determine if data/answeres should be sent to the host
* the previous RX section should be clarify that behaviour.
*/
/* Flag management - Only allow one string to be sent per action */
if (data != NULL && len > 0 && LineEncoding1.BaudRateBPS)
{
LED1_ON;
/* Select the Serial Tx Endpoint */
Endpoint_SelectEndpoint(CDC1_TX_EPADDR);
/* Write the String to the Endpoint */
Endpoint_Write_Stream_LE(data, len, NULL);
/* Finalize the stream transfer to send the last packet */
Endpoint_ClearIN();
/* Wait until the endpoint is ready for another packet */
Endpoint_WaitUntilReady();
/* Send an empty packet to ensure that the host does not buffer data sent to it */
Endpoint_ClearIN();
LED1_OFF;
}
}
/** Function to manage CDC data transmission and reception to and from the host for the second CDC interface,
* which sends all data received from a node (mux) during USART to the host.
*/
void CDC2_Task(void)
{
/* Device must be connected and configured for the task to run */
if (USB_DeviceState != DEVICE_STATE_Configured)
return;
//===========================================================================
/* Select the Serial Rx Endpoint */
Endpoint_SelectEndpoint(CDC2_RX_EPADDR);
/* Check to see if any data has been received */
if (Endpoint_IsOUTReceived())
{
/* Create a temp buffer big enough to hold the incoming endpoint packet */
uint8_t Buffer[Endpoint_BytesInEndpoint()];
/* Remember how large the incoming packet is */
uint16_t DataLength = Endpoint_BytesInEndpoint();
/* Read in the incoming packet into the buffer */
Endpoint_Read_Stream_LE(&Buffer, DataLength, NULL);
/* Finalize the stream transfer to send the last packet */
Endpoint_ClearOUT();
// TODO at this point send the data to the USART
// Send USART &Buffer
for (uint16_t i = 0; i < DataLength; i++)
{
uart_putc(Buffer[i]);
}
}
//return;
//===========================================================================
uint8_t outBuffer[OUTPUT_BUFFER_SIZE];
// TODO read the USART data and send them to the host
// Fill &Buffer with USART data or send the USART input buffer direct
uint16_t cnt = 0;
int c = uart_getc();
while (!(c & UART_NO_DATA) && cnt < OUTPUT_BUFFER_SIZE)
{
//LED0_ON;
outBuffer[cnt] = c;
c = uart_getc();
cnt++;
}
/*
cnt = 1;
outBuffer[0] = '2';
*/
// send the data which was received from the uart connection
if (cnt > 0)
{
/* Select the Serial Tx Endpoint */
Endpoint_SelectEndpoint(CDC2_TX_EPADDR);
/* Write the received data to the endpoint */
Endpoint_Write_Stream_LE(&outBuffer, cnt, NULL);
/* Finalize the stream transfer to send the last packet */
Endpoint_ClearIN();
/* Wait until the endpoint is ready for the next packet */
Endpoint_WaitUntilReady();
/* Send an empty packet to prevent host buffering */
Endpoint_ClearIN();
}
}