source: arduino-1-6-7/trunk/fuentes/arduino-ide-amd64/hardware/arduino/avr/firmwares/atmegaxxu2/arduino-usbserial/Arduino-usbserial.c @ 4837

Last change on this file since 4837 was 4837, checked in by daduve, 2 years ago

Adding new version

File size: 8.3 KB
Line 
1/*
2             LUFA Library
3     Copyright (C) Dean Camera, 2010.
4             
5  dean [at] fourwalledcubicle [dot] com
6      www.fourwalledcubicle.com
7*/
8
9/*
10  Copyright 2010  Dean Camera (dean [at] fourwalledcubicle [dot] com)
11
12  Permission to use, copy, modify, distribute, and sell this
13  software and its documentation for any purpose is hereby granted
14  without fee, provided that the above copyright notice appear in
15  all copies and that both that the copyright notice and this
16  permission notice and warranty disclaimer appear in supporting
17  documentation, and that the name of the author not be used in
18  advertising or publicity pertaining to distribution of the
19  software without specific, written prior permission.
20
21  The author disclaim all warranties with regard to this
22  software, including all implied warranties of merchantability
23  and fitness.  In no event shall the author be liable for any
24  special, indirect or consequential damages or any damages
25  whatsoever resulting from loss of use, data or profits, whether
26  in an action of contract, negligence or other tortious action,
27  arising out of or in connection with the use or performance of
28  this software.
29*/
30
31/** \file
32 *
33 *  Main source file for the Arduino-usbserial project. This file contains the main tasks of
34 *  the project and is responsible for the initial application hardware configuration.
35 */
36
37#include "Arduino-usbserial.h"
38
39/** Circular buffer to hold data from the host before it is sent to the device via the serial port. */
40RingBuff_t USBtoUSART_Buffer;
41
42/** Circular buffer to hold data from the serial port before it is sent to the host. */
43RingBuff_t USARTtoUSB_Buffer;
44
45/** Pulse generation counters to keep track of the number of milliseconds remaining for each pulse type */
46volatile struct
47{
48        uint8_t TxLEDPulse; /**< Milliseconds remaining for data Tx LED pulse */
49        uint8_t RxLEDPulse; /**< Milliseconds remaining for data Rx LED pulse */
50        uint8_t PingPongLEDPulse; /**< Milliseconds remaining for enumeration Tx/Rx ping-pong LED pulse */
51} PulseMSRemaining;
52
53/** LUFA CDC Class driver interface configuration and state information. This structure is
54 *  passed to all CDC Class driver functions, so that multiple instances of the same class
55 *  within a device can be differentiated from one another.
56 */
57USB_ClassInfo_CDC_Device_t VirtualSerial_CDC_Interface =
58        {
59                .Config = 
60                        {
61                                .ControlInterfaceNumber         = 0,
62
63                                .DataINEndpointNumber           = CDC_TX_EPNUM,
64                                .DataINEndpointSize             = CDC_TXRX_EPSIZE,
65                                .DataINEndpointDoubleBank       = false,
66
67                                .DataOUTEndpointNumber          = CDC_RX_EPNUM,
68                                .DataOUTEndpointSize            = CDC_TXRX_EPSIZE,
69                                .DataOUTEndpointDoubleBank      = false,
70
71                                .NotificationEndpointNumber     = CDC_NOTIFICATION_EPNUM,
72                                .NotificationEndpointSize       = CDC_NOTIFICATION_EPSIZE,
73                                .NotificationEndpointDoubleBank = false,
74                        },
75        };
76
77/** Main program entry point. This routine contains the overall program flow, including initial
78 *  setup of all components and the main program loop.
79 */
80int main(void)
81{
82        SetupHardware();
83       
84        RingBuffer_InitBuffer(&USBtoUSART_Buffer);
85        RingBuffer_InitBuffer(&USARTtoUSB_Buffer);
86
87        sei();
88
89        for (;;)
90        {
91                /* Only try to read in bytes from the CDC interface if the transmit buffer is not full */
92                if (!(RingBuffer_IsFull(&USBtoUSART_Buffer)))
93                {
94                        int16_t ReceivedByte = CDC_Device_ReceiveByte(&VirtualSerial_CDC_Interface);
95
96                        /* Read bytes from the USB OUT endpoint into the USART transmit buffer */
97                        if (!(ReceivedByte < 0))
98                          RingBuffer_Insert(&USBtoUSART_Buffer, ReceivedByte);
99                }
100               
101                /* Check if the UART receive buffer flush timer has expired or the buffer is nearly full */
102                RingBuff_Count_t BufferCount = RingBuffer_GetCount(&USARTtoUSB_Buffer);
103                if ((TIFR0 & (1 << TOV0)) || (BufferCount > BUFFER_NEARLY_FULL))
104                {
105                        TIFR0 |= (1 << TOV0);
106
107                        if (USARTtoUSB_Buffer.Count) {
108                                LEDs_TurnOnLEDs(LEDMASK_TX);
109                                PulseMSRemaining.TxLEDPulse = TX_RX_LED_PULSE_MS;
110                        }
111
112                        /* Read bytes from the USART receive buffer into the USB IN endpoint */
113                        while (BufferCount--)
114                          CDC_Device_SendByte(&VirtualSerial_CDC_Interface, RingBuffer_Remove(&USARTtoUSB_Buffer));
115                         
116                        /* Turn off TX LED(s) once the TX pulse period has elapsed */
117                        if (PulseMSRemaining.TxLEDPulse && !(--PulseMSRemaining.TxLEDPulse))
118                          LEDs_TurnOffLEDs(LEDMASK_TX);
119
120                        /* Turn off RX LED(s) once the RX pulse period has elapsed */
121                        if (PulseMSRemaining.RxLEDPulse && !(--PulseMSRemaining.RxLEDPulse))
122                          LEDs_TurnOffLEDs(LEDMASK_RX);
123                }
124               
125                /* Load the next byte from the USART transmit buffer into the USART */
126                if (!(RingBuffer_IsEmpty(&USBtoUSART_Buffer))) {
127                  Serial_TxByte(RingBuffer_Remove(&USBtoUSART_Buffer));
128                       
129                        LEDs_TurnOnLEDs(LEDMASK_RX);
130                        PulseMSRemaining.RxLEDPulse = TX_RX_LED_PULSE_MS;
131                }
132               
133                CDC_Device_USBTask(&VirtualSerial_CDC_Interface);
134                USB_USBTask();
135        }
136}
137
138/** Configures the board hardware and chip peripherals for the demo's functionality. */
139void SetupHardware(void)
140{
141        /* Disable watchdog if enabled by bootloader/fuses */
142        MCUSR &= ~(1 << WDRF);
143        wdt_disable();
144
145        /* Hardware Initialization */
146        Serial_Init(9600, false);
147        LEDs_Init();
148        USB_Init();
149
150        /* Start the flush timer so that overflows occur rapidly to push received bytes to the USB interface */
151        TCCR0B = (1 << CS02);
152       
153        /* Pull target /RESET line high */
154        AVR_RESET_LINE_PORT |= AVR_RESET_LINE_MASK;
155        AVR_RESET_LINE_DDR  |= AVR_RESET_LINE_MASK;
156}
157
158/** Event handler for the library USB Configuration Changed event. */
159void EVENT_USB_Device_ConfigurationChanged(void)
160{
161        CDC_Device_ConfigureEndpoints(&VirtualSerial_CDC_Interface);
162}
163
164/** Event handler for the library USB Unhandled Control Request event. */
165void EVENT_USB_Device_UnhandledControlRequest(void)
166{
167        CDC_Device_ProcessControlRequest(&VirtualSerial_CDC_Interface);
168}
169
170/** Event handler for the CDC Class driver Line Encoding Changed event.
171 *
172 *  \param[in] CDCInterfaceInfo  Pointer to the CDC class interface configuration structure being referenced
173 */
174void EVENT_CDC_Device_LineEncodingChanged(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo)
175{
176        uint8_t ConfigMask = 0;
177
178        switch (CDCInterfaceInfo->State.LineEncoding.ParityType)
179        {
180                case CDC_PARITY_Odd:
181                        ConfigMask = ((1 << UPM11) | (1 << UPM10));             
182                        break;
183                case CDC_PARITY_Even:
184                        ConfigMask = (1 << UPM11);             
185                        break;
186        }
187
188        if (CDCInterfaceInfo->State.LineEncoding.CharFormat == CDC_LINEENCODING_TwoStopBits)
189          ConfigMask |= (1 << USBS1);
190
191        switch (CDCInterfaceInfo->State.LineEncoding.DataBits)
192        {
193                case 6:
194                        ConfigMask |= (1 << UCSZ10);
195                        break;
196                case 7:
197                        ConfigMask |= (1 << UCSZ11);
198                        break;
199                case 8:
200                        ConfigMask |= ((1 << UCSZ11) | (1 << UCSZ10));
201                        break;
202        }
203
204        /* Must turn off USART before reconfiguring it, otherwise incorrect operation may occur */
205        UCSR1B = 0;
206        UCSR1A = 0;
207        UCSR1C = 0;
208
209        /* Special case 57600 baud for compatibility with the ATmega328 bootloader. */ 
210        UBRR1  = (CDCInterfaceInfo->State.LineEncoding.BaudRateBPS == 57600)
211                         ? SERIAL_UBBRVAL(CDCInterfaceInfo->State.LineEncoding.BaudRateBPS)
212                         : SERIAL_2X_UBBRVAL(CDCInterfaceInfo->State.LineEncoding.BaudRateBPS); 
213
214        UCSR1C = ConfigMask;
215        UCSR1A = (CDCInterfaceInfo->State.LineEncoding.BaudRateBPS == 57600) ? 0 : (1 << U2X1);
216        UCSR1B = ((1 << RXCIE1) | (1 << TXEN1) | (1 << RXEN1));
217}
218
219/** ISR to manage the reception of data from the serial port, placing received bytes into a circular buffer
220 *  for later transmission to the host.
221 */
222ISR(USART1_RX_vect, ISR_BLOCK)
223{
224        uint8_t ReceivedByte = UDR1;
225
226        if (USB_DeviceState == DEVICE_STATE_Configured)
227          RingBuffer_Insert(&USARTtoUSB_Buffer, ReceivedByte);
228}
229
230/** Event handler for the CDC Class driver Host-to-Device Line Encoding Changed event.
231 *
232 *  \param[in] CDCInterfaceInfo  Pointer to the CDC class interface configuration structure being referenced
233 */
234void EVENT_CDC_Device_ControLineStateChanged(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo)
235{
236        bool CurrentDTRState = (CDCInterfaceInfo->State.ControlLineStates.HostToDevice & CDC_CONTROL_LINE_OUT_DTR);
237
238        if (CurrentDTRState)
239          AVR_RESET_LINE_PORT &= ~AVR_RESET_LINE_MASK;
240        else
241          AVR_RESET_LINE_PORT |= AVR_RESET_LINE_MASK;
242}
Note: See TracBrowser for help on using the repository browser.