]> git.donarmstrong.com Git - qmk_firmware.git/blob - tmk_core/protocol/lufa/LUFA-git/LUFA/Drivers/USB/Core/AVR8/Pipe_AVR8.c
fc99ae416d808d43a604a3e45bd7f3e9b34165ad
[qmk_firmware.git] / tmk_core / protocol / lufa / LUFA-git / LUFA / Drivers / USB / Core / AVR8 / Pipe_AVR8.c
1 /*
2              LUFA Library
3      Copyright (C) Dean Camera, 2014.
4
5   dean [at] fourwalledcubicle [dot] com
6            www.lufa-lib.org
7 */
8
9 /*
10   Copyright 2014  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 disclaims 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 #include "../../../../Common/Common.h"
32 #if (ARCH == ARCH_AVR8)
33
34 #define  __INCLUDE_FROM_USB_DRIVER
35 #include "../USBMode.h"
36
37 #if defined(USB_CAN_BE_HOST)
38
39 #include "../Pipe.h"
40
41 uint8_t USB_Host_ControlPipeSize = PIPE_CONTROLPIPE_DEFAULT_SIZE;
42
43 bool Pipe_ConfigurePipeTable(const USB_Pipe_Table_t* const Table,
44                              const uint8_t Entries)
45 {
46         for (uint8_t i = 0; i < Entries; i++)
47         {
48                 if (!(Table[i].Address))
49                   continue;
50
51                 if (!(Pipe_ConfigurePipe(Table[i].Address, Table[i].Type, Table[i].EndpointAddress, Table[i].Size, Table[i].Banks)))
52                 {
53                         return false;
54                 }
55         }
56
57         return true;
58 }
59
60 bool Pipe_ConfigurePipe(const uint8_t Address,
61                         const uint8_t Type,
62                         const uint8_t EndpointAddress,
63                         const uint16_t Size,
64                         const uint8_t Banks)
65 {
66         uint8_t Number = (Address & PIPE_EPNUM_MASK);
67         uint8_t Token  = (Address & PIPE_DIR_IN) ? PIPE_TOKEN_IN : PIPE_TOKEN_OUT;
68
69         if (Number >= PIPE_TOTAL_PIPES)
70           return false;
71
72         if (Type == EP_TYPE_CONTROL)
73           Token = PIPE_TOKEN_SETUP;
74
75 #if defined(ORDERED_EP_CONFIG)
76         Pipe_SelectPipe(Number);
77         Pipe_EnablePipe();
78
79         UPCFG1X = 0;
80
81         UPCFG0X = ((Type << EPTYPE0) | Token | ((EndpointAddress & PIPE_EPNUM_MASK) << PEPNUM0));
82         UPCFG1X = ((1 << ALLOC) | ((Banks > 1) ? (1 << EPBK0) : 0) | Pipe_BytesToEPSizeMask(Size));
83
84         Pipe_SetInfiniteINRequests();
85
86         return Pipe_IsConfigured();
87 #else
88         for (uint8_t PNum = Number; PNum < PIPE_TOTAL_PIPES; PNum++)
89         {
90                 uint8_t UPCFG0XTemp;
91                 uint8_t UPCFG1XTemp;
92                 uint8_t UPCFG2XTemp;
93                 uint8_t UPIENXTemp;
94
95                 Pipe_SelectPipe(PNum);
96
97                 if (PNum == Number)
98                 {
99                         UPCFG0XTemp = ((Type << EPTYPE0) | Token | ((EndpointAddress & PIPE_EPNUM_MASK) << PEPNUM0));
100                         UPCFG1XTemp = ((1 << ALLOC) | ((Banks > 1) ? (1 << EPBK0) : 0) | Pipe_BytesToEPSizeMask(Size));
101                         UPCFG2XTemp = 0;
102                         UPIENXTemp  = 0;
103                 }
104                 else
105                 {
106                         UPCFG0XTemp = UPCFG0X;
107                         UPCFG1XTemp = UPCFG1X;
108                         UPCFG2XTemp = UPCFG2X;
109                         UPIENXTemp  = UPIENX;
110                 }
111
112                 if (!(UPCFG1XTemp & (1 << ALLOC)))
113                   continue;
114
115                 Pipe_DisablePipe();
116                 UPCFG1X &= ~(1 << ALLOC);
117
118                 Pipe_EnablePipe();
119                 UPCFG0X = UPCFG0XTemp;
120                 UPCFG1X = UPCFG1XTemp;
121                 UPCFG2X = UPCFG2XTemp;
122                 UPIENX  = UPIENXTemp;
123
124                 Pipe_SetInfiniteINRequests();
125
126                 if (!(Pipe_IsConfigured()))
127                   return false;
128         }
129
130         Pipe_SelectPipe(Number);
131         return true;
132 #endif
133 }
134
135 void Pipe_ClearPipes(void)
136 {
137         UPINT = 0;
138
139         for (uint8_t PNum = 0; PNum < PIPE_TOTAL_PIPES; PNum++)
140         {
141                 Pipe_SelectPipe(PNum);
142                 UPIENX  = 0;
143                 UPINTX  = 0;
144                 UPCFG1X = 0;
145                 Pipe_DisablePipe();
146         }
147 }
148
149 bool Pipe_IsEndpointBound(const uint8_t EndpointAddress)
150 {
151         uint8_t PrevPipeNumber = Pipe_GetCurrentPipe();
152
153         for (uint8_t PNum = 0; PNum < PIPE_TOTAL_PIPES; PNum++)
154         {
155                 Pipe_SelectPipe(PNum);
156
157                 if (!(Pipe_IsConfigured()))
158                   continue;
159
160                 if (Pipe_GetBoundEndpointAddress() == EndpointAddress)
161                   return true;
162         }
163
164         Pipe_SelectPipe(PrevPipeNumber);
165         return false;
166 }
167
168 uint8_t Pipe_WaitUntilReady(void)
169 {
170         #if (USB_STREAM_TIMEOUT_MS < 0xFF)
171         uint8_t  TimeoutMSRem = USB_STREAM_TIMEOUT_MS;
172         #else
173         uint16_t TimeoutMSRem = USB_STREAM_TIMEOUT_MS;
174         #endif
175
176         uint16_t PreviousFrameNumber = USB_Host_GetFrameNumber();
177
178         for (;;)
179         {
180                 if (Pipe_GetPipeToken() == PIPE_TOKEN_IN)
181                 {
182                         if (Pipe_IsINReceived())
183                           return PIPE_READYWAIT_NoError;
184                 }
185                 else
186                 {
187                         if (Pipe_IsOUTReady())
188                           return PIPE_READYWAIT_NoError;
189                 }
190
191                 if (Pipe_IsStalled())
192                   return PIPE_READYWAIT_PipeStalled;
193                 else if (USB_HostState == HOST_STATE_Unattached)
194                   return PIPE_READYWAIT_DeviceDisconnected;
195
196                 uint16_t CurrentFrameNumber = USB_Host_GetFrameNumber();
197
198                 if (CurrentFrameNumber != PreviousFrameNumber)
199                 {
200                         PreviousFrameNumber = CurrentFrameNumber;
201
202                         if (!(TimeoutMSRem--))
203                           return PIPE_READYWAIT_Timeout;
204                 }
205         }
206 }
207
208 #endif
209
210 #endif