Fri, 17 Nov 2017 10:13:31 +0100
proper configuration, homing and planner optimization
2 | 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. */ | |
40 | RingBuff_t USBtoUSART_Buffer; | |
41 | ||
42 | /** Circular buffer to hold data from the serial port before it is sent to the host. */ | |
43 | RingBuff_t USARTtoUSB_Buffer; | |
44 | ||
45 | /** Pulse generation counters to keep track of the number of milliseconds remaining for each pulse type */ | |
46 | volatile 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 | */ | |
57 | USB_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 | */ | |
80 | int 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. */ | |
139 | void 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. */ | |
159 | void 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. */ | |
165 | void 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 | */ | |
174 | void 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 | */ | |
222 | ISR(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 | */ | |
234 | void 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 | } |