]> git.donarmstrong.com Git - qmk_firmware.git/blob - protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/AVR8/Pipe_AVR8.c
Squashed 'tmk_core/' content from commit 05caacc
[qmk_firmware.git] / protocol / lufa / LUFA-120730 / LUFA / Drivers / USB / Core / AVR8 / Pipe_AVR8.c
1 /*\r
2              LUFA Library\r
3      Copyright (C) Dean Camera, 2012.\r
4 \r
5   dean [at] fourwalledcubicle [dot] com\r
6            www.lufa-lib.org\r
7 */\r
8 \r
9 /*\r
10   Copyright 2012  Dean Camera (dean [at] fourwalledcubicle [dot] com)\r
11 \r
12   Permission to use, copy, modify, distribute, and sell this\r
13   software and its documentation for any purpose is hereby granted\r
14   without fee, provided that the above copyright notice appear in\r
15   all copies and that both that the copyright notice and this\r
16   permission notice and warranty disclaimer appear in supporting\r
17   documentation, and that the name of the author not be used in\r
18   advertising or publicity pertaining to distribution of the\r
19   software without specific, written prior permission.\r
20 \r
21   The author disclaim all warranties with regard to this\r
22   software, including all implied warranties of merchantability\r
23   and fitness.  In no event shall the author be liable for any\r
24   special, indirect or consequential damages or any damages\r
25   whatsoever resulting from loss of use, data or profits, whether\r
26   in an action of contract, negligence or other tortious action,\r
27   arising out of or in connection with the use or performance of\r
28   this software.\r
29 */\r
30 \r
31 #include "../../../../Common/Common.h"\r
32 #if (ARCH == ARCH_AVR8)\r
33 \r
34 #define  __INCLUDE_FROM_USB_DRIVER\r
35 #include "../USBMode.h"\r
36 \r
37 #if defined(USB_CAN_BE_HOST)\r
38 \r
39 #include "../Pipe.h"\r
40 \r
41 uint8_t USB_Host_ControlPipeSize = PIPE_CONTROLPIPE_DEFAULT_SIZE;\r
42 \r
43 bool Pipe_ConfigurePipeTable(const USB_Pipe_Table_t* const Table,\r
44                              const uint8_t Entries)\r
45 {\r
46         for (uint8_t i = 0; i < Entries; i++)\r
47         {\r
48                 if (!(Table[i].Address))\r
49                   continue;\r
50         \r
51                 if (!(Pipe_ConfigurePipe(Table[i].Address, Table[i].Type, Table[i].EndpointAddress, Table[i].Size, Table[i].Banks)))\r
52                 {\r
53                         return false;\r
54                 }\r
55         }\r
56         \r
57         return true;\r
58 }\r
59 \r
60 bool Pipe_ConfigurePipe(const uint8_t Address,\r
61                         const uint8_t Type,\r
62                         const uint8_t EndpointAddress,\r
63                         const uint16_t Size,\r
64                         const uint8_t Banks)\r
65 {\r
66         uint8_t Number = (Address & PIPE_EPNUM_MASK);\r
67         uint8_t Token  = (Address & PIPE_DIR_IN) ? PIPE_TOKEN_IN : PIPE_TOKEN_OUT;\r
68         \r
69         if (Number >= PIPE_TOTAL_PIPES)\r
70           return false;\r
71 \r
72         if (Type == EP_TYPE_CONTROL)\r
73           Token = PIPE_TOKEN_SETUP;\r
74 \r
75 #if defined(ORDERED_EP_CONFIG)\r
76         Pipe_SelectPipe(Number);\r
77         Pipe_EnablePipe();\r
78 \r
79         UPCFG1X = 0;\r
80 \r
81         UPCFG0X = ((Type << EPTYPE0) | Token | ((EndpointAddress & PIPE_EPNUM_MASK) << PEPNUM0));\r
82         UPCFG1X = ((1 << ALLOC) | ((Banks > 1) ? (1 << EPBK0) : 0) | Pipe_BytesToEPSizeMask(Size));\r
83 \r
84         Pipe_SetInfiniteINRequests();\r
85 \r
86         return Pipe_IsConfigured();\r
87 #else\r
88         for (uint8_t PNum = Number; PNum < PIPE_TOTAL_PIPES; PNum++)\r
89         {\r
90                 uint8_t UPCFG0XTemp;\r
91                 uint8_t UPCFG1XTemp;\r
92                 uint8_t UPCFG2XTemp;\r
93                 uint8_t UPIENXTemp;\r
94 \r
95                 Pipe_SelectPipe(PNum);\r
96 \r
97                 if (PNum == Number)\r
98                 {\r
99                         UPCFG0XTemp = ((Type << EPTYPE0) | Token | ((EndpointAddress & PIPE_EPNUM_MASK) << PEPNUM0));\r
100                         UPCFG1XTemp = ((1 << ALLOC) | Banks | Pipe_BytesToEPSizeMask(Size));\r
101                         UPCFG2XTemp = 0;\r
102                         UPIENXTemp  = 0;\r
103                 }\r
104                 else\r
105                 {\r
106                         UPCFG0XTemp = UPCFG0X;\r
107                         UPCFG1XTemp = UPCFG1X;\r
108                         UPCFG2XTemp = UPCFG2X;\r
109                         UPIENXTemp  = UPIENX;\r
110                 }\r
111 \r
112                 if (!(UPCFG1XTemp & (1 << ALLOC)))\r
113                   continue;\r
114 \r
115                 Pipe_DisablePipe();\r
116                 UPCFG1X &= ~(1 << ALLOC);\r
117 \r
118                 Pipe_EnablePipe();\r
119                 UPCFG0X = UPCFG0XTemp;\r
120                 UPCFG1X = UPCFG1XTemp;\r
121                 UPCFG2X = UPCFG2XTemp;\r
122                 UPIENX  = UPIENXTemp;\r
123 \r
124                 Pipe_SetInfiniteINRequests();\r
125 \r
126                 if (!(Pipe_IsConfigured()))\r
127                   return false;\r
128         }\r
129 \r
130         Pipe_SelectPipe(Number);\r
131         return true;\r
132 #endif\r
133 }\r
134 \r
135 void Pipe_ClearPipes(void)\r
136 {\r
137         UPINT = 0;\r
138 \r
139         for (uint8_t PNum = 0; PNum < PIPE_TOTAL_PIPES; PNum++)\r
140         {\r
141                 Pipe_SelectPipe(PNum);\r
142                 UPIENX  = 0;\r
143                 UPINTX  = 0;\r
144                 UPCFG1X = 0;\r
145                 Pipe_DisablePipe();\r
146         }\r
147 }\r
148 \r
149 bool Pipe_IsEndpointBound(const uint8_t EndpointAddress)\r
150 {\r
151         uint8_t PrevPipeNumber = Pipe_GetCurrentPipe();\r
152 \r
153         for (uint8_t PNum = 0; PNum < PIPE_TOTAL_PIPES; PNum++)\r
154         {\r
155                 Pipe_SelectPipe(PNum);\r
156 \r
157                 if (!(Pipe_IsConfigured()))\r
158                   continue;\r
159 \r
160                 if (Pipe_GetBoundEndpointAddress() == EndpointAddress)\r
161                   return true;\r
162         }\r
163 \r
164         Pipe_SelectPipe(PrevPipeNumber);\r
165         return false;\r
166 }\r
167 \r
168 uint8_t Pipe_WaitUntilReady(void)\r
169 {\r
170         #if (USB_STREAM_TIMEOUT_MS < 0xFF)\r
171         uint8_t  TimeoutMSRem = USB_STREAM_TIMEOUT_MS;\r
172         #else\r
173         uint16_t TimeoutMSRem = USB_STREAM_TIMEOUT_MS;\r
174         #endif\r
175 \r
176         uint16_t PreviousFrameNumber = USB_Host_GetFrameNumber();\r
177 \r
178         for (;;)\r
179         {\r
180                 if (Pipe_GetPipeToken() == PIPE_TOKEN_IN)\r
181                 {\r
182                         if (Pipe_IsINReceived())\r
183                           return PIPE_READYWAIT_NoError;\r
184                 }\r
185                 else\r
186                 {\r
187                         if (Pipe_IsOUTReady())\r
188                           return PIPE_READYWAIT_NoError;\r
189                 }\r
190 \r
191                 if (Pipe_IsStalled())\r
192                   return PIPE_READYWAIT_PipeStalled;\r
193                 else if (USB_HostState == HOST_STATE_Unattached)\r
194                   return PIPE_READYWAIT_DeviceDisconnected;\r
195 \r
196                 uint16_t CurrentFrameNumber = USB_Host_GetFrameNumber();\r
197 \r
198                 if (CurrentFrameNumber != PreviousFrameNumber)\r
199                 {\r
200                         PreviousFrameNumber = CurrentFrameNumber;\r
201 \r
202                         if (!(TimeoutMSRem--))\r
203                           return PIPE_READYWAIT_Timeout;\r
204                 }\r
205         }\r
206 }\r
207 \r
208 #endif\r
209 \r
210 #endif\r