📄 host_811.lst
字号:
173 1 else // for current SETUP/OUT tokens
174 1 {
175 2 if(xferLen) // only when there are
176 2 SL811BufWrite(data0,buffer,xferLen); // data to transfer on USB
177 2 cmd = sDATA0_WR;
178 2
179 2 }
C51 COMPILER V7.06 HOST_811 07/30/2008 08:56:14 PAGE 4
180 1 //------------------------------------------------
181 1 // For EP0's IN/OUT token data, start with DATA1
182 1 // Control Endpoint0's status stage.
183 1 // For data endpoint, IN/OUT data, start ????
184 1 //------------------------------------------------
185 1 if (endpoint == 0 && pid != PID_SETUP) // for Ep0's IN/OUT token
186 1 cmd |= 0x40; // always set DATA1
187 1
188 1 //------------------------------------------------
189 1 // Arming of USB data transfer for the first pkt
190 1 //------------------------------------------------
191 1 SL811Write(EP0Status,((endpoint&0x0F)|pid)); // PID + EP address
192 1 SL811Write(EP0Counter,usbaddr); // USB address
193 1 SL811Write(EP0Address,data0); // buffer address, start with "data0"
194 1 SL811Write(EP0XferLen,xferLen); // data transfer length
195 1 SL811Write(IntStatus,INT_CLEAR); // clear interrupt status
196 1 SL811Write(EP0Control,cmd); // Enable ARM and USB transfer start here
197 1 //------------------------------------------------
198 1 // Main loop for completing a wLen data trasnfer
199 1 //---------------------- --------------------------
200 1 while(TRUE)
201 1 {
202 2 //---------------Wait for done interrupt------------------
203 2 while(TRUE) // always ensure requested device is
204 2 { // inserted at all time, then you will
205 3 intr = SL811Read(IntStatus); // wait for interrupt to be done, and
206 3 if((intr & USB_RESET) || (intr & INSERT_REMOVE)) // proceed to parse result from slave
207 3 { // device.
208 4 USB_Control.DATA_STOP = TRUE; // if dhevice is removed, set DATA_STOP
209 4 return FALSE; // flag true, so that main loop will
210 4 } // know tis condition and exit gracefully
211 3 if(intr & USB_A_DONE)
212 3 break; // interrupt done !!!
213 3 }
214 2
215 2 SL811Write(IntStatus,INT_CLEAR); // clear interrupt status
216 2 result = SL811Read(EP0Status); // read EP0status register
217 2 remainder = SL811Read(EP0Counter); // remainder value in last pkt xfer
218 2
219 2 //-------------------------ACK----------------------------
220 2 if (result & EP0_ACK) // Transmission ACK
221 2 {
222 3
223 3 // SETUP TOKEN
224 3 if(pid == PID_SETUP) // do nothing for SETUP/OUT token
225 3 break; // exit while(1) immediately
226 3
227 3 // OUT TOKEN
228 3 else if(pid == PID_OUT)
229 3 break;
230 3
231 3 // IN TOKEN
232 3 else if(pid == PID_IN)
233 3 { // for IN token only
234 4 wLen -= (WORD)xferLen; // update remainding wLen value
235 4 cmd ^= 0x40; // toggle DATA0/DATA1
236 4 dataX++; // point to next dataX
237 4
238 4 //------------------------------------------------
239 4 // If host requested for more data than the slave
240 4 // have, and if the slave's data len is a multiple
241 4 // of its endpoint payload size/last xferLen. Do
C51 COMPILER V7.06 HOST_811 07/30/2008 08:56:14 PAGE 5
242 4 // not overwrite data in previous buffer.
243 4 //------------------------------------------------
244 4 if(remainder==xferLen) // empty data detected
245 4 bufLen = 0; // do not overwriten previous data
246 4 else // reset bufLen to zero
247 4 bufLen = xferLen; // update previous buffer length
248 4
249 4 //------------------------------------------------
250 4 // Arm for next data transfer when requested data
251 4 // length have not reach zero, i.e. wLen!=0, and
252 4 // last xferlen of data was completed, i.e.
253 4 // remainder is equal to zero, not a short pkt
254 4 //------------------------------------------------
255 4 if(!remainder && wLen) // remainder==0 when last xferLen
256 4 { // was all completed or wLen!=0
257 5 addr = (dataX & 1) ? data1:data0; // select next address for data
258 5 xferLen = (BYTE)(wLen>=wPayload) ? wPayload:wLen; // get data length required
259 5 // if (FULL_SPEED) // sync with SOF transfer
260 5 cmd |= 0x20; // always sync SOF when FS, regardless
261 5 SL811Write(EP0XferLen, xferLen); // select next xfer length
262 5 SL811Write(EP0Address, addr); // data buffer addr
263 5 SL811Write(IntStatus,INT_CLEAR); // is a LS is on Hub.
264 5 SL811Write(EP0Control,cmd); // Enable USB transfer and re-arm
265 5 }
266 4
267 4 //------------------------------------------------
268 4 // Copy last IN token data pkt from prev transfer
269 4 // Check if there was data available during the
270 4 // last data transfer
271 4 //------------------------------------------------
272 4 if(bufLen)
273 4 {
274 5 SL811BufRead(((dataX&1)?data0:data1), buffer, bufLen);
275 5 buffer += bufLen;
276 5 }
277 4
278 4 //------------------------------------------------
279 4 // Terminate on short packets, i.e. remainder!=0
280 4 // a short packet or empty data packet OR when
281 4 // requested data len have completed, i.e.wLen=0
282 4 // For a LOWSPEED device, the 1st device descp,
283 4 // wPayload is default to 64-byte, LS device will
284 4 // only send back a max of 8-byte device descp,
285 4 // and host detect this as a short packet, and
286 4 // terminate with OUT status stage
287 4 //------------------------------------------------
288 4 if(remainder || !wLen)
289 4 break;
290 4 }
291 3 }
292 2
293 2 //-------------------------NAK----------------------------
294 2 if (result & EP0_NAK) // NAK Detected
295 2 {
296 3 if(endpoint==0) // on ep0 during enumeration of LS device
297 3 { // happen when slave is not fast enough,
298 4 SL811Write(IntStatus,INT_CLEAR); // clear interrupt status, need to
299 4 SL811Write(EP0Control,cmd); // re-arm and request for last cmd, IN token
300 4 result = 0; // respond to NAK status only
301 4 }
302 3 else // normal data endpoint, exit now !!! , non-zero ep
303 3 break; // main loop control the interval polling
C51 COMPILER V7.06 HOST_811 07/30/2008 08:56:14 PAGE 6
304 3 }
305 2
306 2 //-----------------------TIMEOUT--------------------------
307 2 if (result & EP0_TIMEOUT) // TIMEOUT Detected
308 2 {
309 3 if(endpoint==0) // happens when hub enumeration
310 3 {
311 4 if(++timeout >= TIMEOUT_RETRY)
312 4 {
313 5 timeout--;
314 5 break; // exit on the timeout detected
315 5 }
316 4 SL811Write(IntStatus,INT_CLEAR); // clear interrupt status, need to
317 4 SL811Write(EP0Control,cmd); // re-arm and request for last cmd again
318 4 }
319 3 else
320 3 { // all other data endpoint, data transfer
321 4 USB_Control.TIMEOUT_ERR = TRUE; // failed, set flag to terminate transfer
322 4 break; // happens when data transfer on a device
323 4 } // through the hub
324 3 }
325 2
326 2 //-----------------------STALL----------------------------
327 2 if (result & EP0_STALL) // STALL detected
328 2 return TRUE; // for unsupported request.
329 2
330 2 //----------------------OVEFLOW---------------------------
331 2 if (result & EP0_OVERFLOW) // OVERFLOW detected
332 2 break;
333 2 //-----------------------ERROR----------------------------
334 2 if (result & EP0_ERROR) // ERROR detected
335 2 break;
336 2 } // end of While(1)
337 1
338 1 if (result & EP0_ACK) // on ACK transmission
339 1 return TRUE; // return OK
340 1
341 1 return FALSE; // fail transmission
342 1 }
343
344 //*****************************************************************************************
345 // Control Endpoint 0's USB Data Xfer
346 // ep0Xfer, endpoint 0 data transfer
347 //*****************************************************************************************
348 BYTE ep0Xfer(BYTE usbaddr, WORD payload, pSetupPKG setup, BYTE *pData)
349 {
350 1 BYTE pid = PID_IN;
351 1 WORD wLen = WordSwap(setup->wLength); // swap back for correct length
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -