blob: fac7f0a1736954223e0b32c3dcb08800b484399a [file] [log] [blame]
b.liue9582032025-04-17 19:18:16 +08001/******************************************************************************
2**
3** INTEL CONFIDENTIAL
4** Copyright 2003-2004 Intel Corporation All Rights Reserved.
5**
6** The source code contained or described herein and all documents
7** related to the source code (Material) are owned by Intel Corporation
8** or its suppliers or licensors. Title to the Material remains with
9** Intel Corporation or its suppliers and licensors. The Material contains
10** trade secrets and proprietary and confidential information of Intel
11** or its suppliers and licensors. The Material is protected by worldwide
12** copyright and trade secret laws and treaty provisions. No part of the
13** Material may be used, copied, reproduced, modified, published, uploaded,
14** posted, transmitted, distributed, or disclosed in any way without Intel's
15** prior express written permission.
16**
17** No license under any patent, copyright, trade secret or other intellectual
18** property right is granted to or conferred upon you by disclosure or
19** delivery of the Materials, either expressly, by implication, inducement,
20** estoppel or otherwise. Any license under such intellectual property rights
21** must be express and approved by Intel in writing.
22**
23** ProtocolManager.c
24******************************************************************************/
25
26/******************************************************************************
27 *
28 * (C)Copyright 2005 - 2011 Marvell. All Rights Reserved.
29 *
30 * THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF MARVELL.
31 * The copyright notice above does not evidence any actual or intended
32 * publication of such source code.
33 * This Module contains Proprietary Information of Marvell and should be
34 * treated as Confidential.
35 * The information in this file is provided for the exclusive use of the
36 * licensees of Marvell.
37 * Such users have the right to use, modify, and incorporate this code into
38 * products for purposes authorized by the license agreement provided they
39 * include this notice and the associated copyright notice with any such
40 * product.
41 * The information in this file is provided "AS IS" without warranty.
42
43 ******************************************************************************/
44
45/******************************************************************************
46 *
47 * The boot ROM protocol is documented in the boot ROM specification. This
48 * implements the protocol over the USB or UART port. It is expected that
49 * the driver for the port has a minimal set of routines to handle receiving
50 * and responding to commands. This file will interpret the data and prepare
51 * the response data for a particular command. The driver is resonsible for
52 * sending and receiving the data over the port.
53 *
54 * Basic process:
55 * - Interrupt is received from one of the ports
56 * - The HandleRequest routine is called to get the command from the port
57 * - Based on the request type either a download request or a JTAG request
58 * is started. At this point the other ports are disabled until the
59 * request is completed.
60 *
61 *
62 ******************************************************************************/
63
64#include "ProtocolManager.h"
65#include "Errors.h"
66#include "misc.h"
67#include "Flash.h"
68#include "FM.h"
69#include "ICU.h"
70#include "tim.h"
71#include "PlatformConfig.h"
72#include "loadoffsets.h"
73#include "nand.h"
74#include "downloader.h"
75#include "TIMDownload.h"
76
77
78#define MAX_RECV_FIFO_LEN (8192)
79__attribute__((aligned(8)))UINT8 receiveBuff[MAX_RECV_FIFO_LEN];
80UCHAR *pRXbuff = receiveBuff;
81
82__attribute__((aligned(8)))UINT8 transmitBuff[MAX_RECV_FIFO_LEN];
83// Here's how to interprit the version
84// MAJOR
85// A (stepping) = 1
86// B (stepping) = 2
87// C (stepping) = 3
88// D (stepping) = 4
89// MINOR
90// This is basically the stepping number, 0=0, 1=1, 2=2 etc
91// For example:
92// A0 = 1000
93// A1 = 1001
94// B2 = 2002
95// C0 = 3000
96// C2 = 3002
97
98
99__attribute__((aligned(4))) UINT8_T preambleString[] = { 0x00, 0xD3, 0x02, 0x2B };
100UINT8_T upload_config_flash_flag = 0;
101UINT8_T upload_get_times_flag = 0;
102UINT8_T upload_times = 1;
103UINT8_T ResetUE = 0;
104UINT8_T ResetDelay = 0;
105extern UINT8_T FlashInitDone;
106
107#if NAND_CODE
108extern UINT_T NandID;
109#endif
110
111#if REPORT_DDR_INFO
112extern UINT_T swd_ddr_vendor_id, swd_ddr_size, swd_flash_id;
113#endif
114
115static ProtocolISR GProtocolISR;
116static pProtocolCmd pGProtocolCmd;
117static __attribute__((aligned(4))) ProtocolRsp GProtocolRsp;
118static ProtocolMsg GProtocolMsg;
119static UINT8_T sProtocolError = NoError;
120
121//Protocol Manager helper routines - should all be 'inline' routines
122pProtocolISR getProtocolISR(void) { return &GProtocolISR; }
123pProtocolCmd getProtocolCmd(void) { return pGProtocolCmd; }
124pProtocolCmd setProtocolCmd(void *addr) { return pGProtocolCmd = (pProtocolCmd) addr; }
125pProtocolRsp getProtocolRsp(void) { return &GProtocolRsp; }
126pProtocolMsg getProtocolMsg(void) { return &GProtocolMsg; }
127void setProtocolError(UINT8_T Error) { sProtocolError = Error; }
128UINT8_T getProtocolError(void) { return sProtocolError; }
129UCHAR * getProtoBuff() { return pRXbuff; }
130void setProtoBuff(UCHAR* pAddr) { pRXbuff = pAddr; }
131void resetProtoBuff() { pRXbuff = receiveBuff; }
132
133
134//Protocol Manager reply routines. Will call into USB API to do the actual send
135UINT_T SendResponse(UINT8_T *pAckBuff, UINT_T size)
136{
137 P_USBAPI_T pUsbApi = getProtocolISR()->plinkedUSB;
138
139 //pointer to the current USB Handle
140 pUsbApi->USB_Send((UINT *)pAckBuff, size, pUsbApi);
141
142 return NoError;
143}
144
145UINT_T SendAck(void)
146{
147 UINT_T Retval = NoError;
148 pProtocolCmd pCmd = getProtocolCmd();
149 pProtocolRsp pRsp = getProtocolRsp();
150
151 pRsp->Command = pCmd->Command;
152 pRsp->Sequence = pCmd->Sequence;
153 pRsp->CID = pCmd->CID;
154 pRsp->Status = Ack;
155 pRsp->Flags = pRsp->Flags & ~(MESSAGE_FLAG);
156 pRsp->Flags = pRsp->Flags | getProtocolMsg()->MessageFlag;
157
158 Retval = SendResponse(&pRsp->Command, pRsp->Length + 6);
159
160 return Retval;
161}
162
163UINT_T SendError(UINT_T ErrorCode){
164
165 UINT_T Retval = NoError;
166 UINT_T RspSize;
167 //UINT_T i;
168 pProtocolCmd pCmd = getProtocolCmd();
169 pProtocolRsp pRsp = getProtocolRsp();
170
171 pRsp->Command = pCmd->Command;
172 pRsp->Sequence = pCmd->Sequence;
173 pRsp->CID = pCmd->CID;
174 pRsp->Status = Nack;
175 pRsp->Flags = getProtocolMsg()->MessageFlag;
176 if(ErrorCode)
177 {
178 pRsp->Length = 4;
179 *(UINT16_T*)&pRsp->Data[0] = ErrorCode & 0x0000FFFF;
180 *(UINT16_T*)&pRsp->Data[2] = (ErrorCode & 0xFFFF0000) >> 16;
181 }
182 else
183 pRsp->Length = 0;
184
185 RspSize = ErrorCode ? 6 + pRsp->Length : 6;
186 Retval = SendResponse(&pRsp->Command, RspSize);
187
188 return Retval;
189}
190
191
192////////////////////////////////////////////////////////////////////////
193// Functions to handle specific commands
194////////////////////////////////////////////////////////////////////////
195
196UINT_T HandleGetVersionCmd()
197{
198 UINT_T Retval= 0, i;
199 pProtocolRsp pRsp;
200
201// UINT8_T *Version = (UINT8_T *)(VERSION_OFFSET + BOOTROMBASEADDR); // legacy way to get version info...
202// Version used to come from BootROM's version info.
203// But now the BootROM's memory space is unavailable to BootLoader.
204// Furthermore, it is probably more appropriate to return the version
205// info of whichever executable is running: BootROM or BootLoader.
206 extern UINT8_T ExecutableVersionInfo[]; // defined in [TBR|BL]_startup.s
207 UINT8_T *pVersion = ExecutableVersionInfo; // new way to get version info.
208
209 pRsp = getProtocolRsp();
210
211 pRsp->Length = 12;
212 memcpy( (void *)&(pRsp->Data[0]), pVersion, 12);
213
214#if REPORT_DDR_INFO
215 pRsp->Length += 8;
216
217 for (i = 0; i < 4; i++)
218 pRsp->Data[12+i] = (swd_ddr_vendor_id >> (8 * i)) & 0xff;
219
220 for (i = 0; i < 4; i++)
221 pRsp->Data[16+i] = (swd_ddr_size >> (8 * i)) & 0xff;
222
223 pRsp->Length += 4;
224
225 for (i = 0; i < 4; i++)
226 pRsp->Data[20+i] = (swd_flash_id >> (8 * i)) & 0xff;
227#endif
228
229 Retval = SendAck();
230
231 return Retval;
232}
233
234UINT_T HandleSelectImageCmd(UINT_T imageType)
235{
236 UINT_T Retval;
237 pProtocolRsp pRsp = getProtocolRsp();
238
239 pRsp->Length = 4;
240
241 *(UINT16_T *)&pRsp->Data[0] = imageType & 0x0000FFFF;
242 *(UINT16_T *)&pRsp->Data[2] = (imageType & 0xFFFF0000) >> 16;
243
244 Retval = SendAck();
245
246 return Retval;
247}
248
249UINT_T HandleVerifyImageCmd()
250{
251 UINT_T Retval= 0;
252
253 getProtocolRsp()->Length = 0;
254
255 if(getProtocolCmd()->Data[0] == Nack)
256 getProtocolISR()->ErrorCode = UnknownImageError;
257
258 Retval = SendAck();
259 return Retval;
260
261}
262
263UINT_T HandleDataHeaderCmd()
264{
265 UINT_T RemainingLen = 0;
266 UINT_T BufferSize = 0;
267 UINT_T NextSize = 0;
268
269 pProtocolRsp pRsp = getProtocolRsp();
270 pProtocolISR pISR = getProtocolISR();
271 pProtocolCmd pCmd = getProtocolCmd();
272
273 pRsp->Length = 4;
274 RemainingLen = *(UINT32_T *)&pCmd->Data[0];
275
276 //check to make sure the data will fit
277 if(RemainingLen > pISR->MaxImageSize)
278 {
279 AddMessageError(REPORT_NOTIFICATION, DownloadImageTooBigError);
280 SendError(DownloadImageTooBigError);
281 pISR->ErrorCode = DownloadImageTooBigError;
282 return NULL;
283 }
284
285 pISR->DataLeft = RemainingLen; //DataLeft indicates how much of the total image remains
286
287 if (pCmd->Flags & FAST_DOWNLOAD)
288 {
289 pRsp->Flags = pRsp->Flags | FAST_DOWNLOAD;
290 pISR->FastDLInProgress = 1;
291 //setup next read for 2KB
292 NextSize = BufferSize = (RemainingLen > FD_BLOCK_SIZE) ? FD_BLOCK_SIZE : RemainingLen;
293 }
294 else
295 {
296 pRsp->Flags = pRsp->Flags & ~FAST_DOWNLOAD;
297 pISR->FastDLInProgress = 0;
298 //setup next read for 2KB
299 BufferSize = (RemainingLen > DATA_BLOCK_SIZE) ? DATA_BLOCK_SIZE : RemainingLen;
300 NextSize = BufferSize + COMMAND_SIZE;
301 }
302
303
304 *(UINT16_T*)&pRsp->Data[0] = BufferSize & 0x0000FFFF;
305 *(UINT16_T*)&pRsp->Data[2] = (BufferSize & 0xFFFF0000) >> 16;
306
307 SendAck();
308
309
310 return NextSize;
311}
312
313UINT_T HandleDataCmd()
314{
315 UINT_T Retval = 0;
316
317 getProtocolCmd()->Command = DownloadDataCmd;
318 getProtocolRsp()->Length = 0;
319
320 SendAck();
321 return Retval;
322}
323
324UINT_T HandleDoneCmd()
325{
326 UINT_T Retval= 0;
327 pProtocolISR pISR = getProtocolISR();
328
329 getProtocolRsp()->Length = 0;
330
331 //reset the status flags
332 pISR->PreambleReceived = FALSE;
333
334 SendAck();
335 return Retval;
336
337}
338
339UINT_T HandleMessageCmd(void){
340 UINT_T Retval= 0;
341
342#if VERBOSE_MODE
343
344 UINT_T mIndex;
345 UINT_T size;
346 UINT_T i;
347 //UINT8_T Buff[LENGTHOFMESSAGES + 6];
348 UINT8_T *Buff = transmitBuff;
349 pProtocolCmd pCmd = getProtocolCmd();
350 pProtocolMsg pMsg = getProtocolMsg();
351
352 //tool sending extra message commands to catch messages
353 //if we don't have any messages, just NACK the message and continue
354 if(pMsg->NumMessagesQueued == 0){
355 SendError(0);
356 return NoError;
357 }
358
359 //must use Buff instead of GProtocolRsp
360 Buff[0] = pCmd->Command;
361 Buff[1] = pCmd->Sequence;
362 Buff[2] = pCmd->CID;
363 Buff[3] = Ack;
364
365 mIndex = pMsg->CurrentMessageIndex;
366 size = pMsg->Lengths[mIndex];
367
368 Buff[5] = size;
369 for(i = 0; i < size; i++)
370 Buff[6+i] = pMsg->Messages[mIndex][i];
371
372 //increment the pointer to the new current message
373 pMsg->CurrentMessageIndex++;
374 pMsg->CurrentMessageIndex %= MAXNUMOFMESSAGES;
375
376 pMsg->NumMessagesQueued--;
377
378 if(pMsg->NumMessagesQueued == 0)
379 pMsg->MessageFlag = 0;
380 else
381 pMsg->MessageFlag = 1;
382
383 //mark flags (message flag message type flag )
384 Buff[4] = (pMsg->MessageFlag | (pMsg->MessageType[mIndex] << 1));
385
386 SendResponse(&Buff[0], 6+size);
387
388#else // end if VERBOSE_MODE
389
390 SendError(0);
391#endif
392 return Retval;
393}
394
395UINT_T HandleDisconnect()
396{
397 UINT start_time;
398 pProtocolISR pISR = getProtocolISR();
399
400 //if there is no linked USB Device, then there was never any protocol transaction
401 if(pISR->plinkedUSB == NULL)
402 return NoError;
403
404 //check to see if there are queued up messages.
405 if( (pISR->DisconnectReceived == TRUE) && getProtocolMsg()->MessageFlag)
406 { //clear disconnect received flag as we now need to wait for a new one
407 pISR->DisconnectReceived = FALSE;
408 //reply with a NAK to allow messages to get sent
409 SendError(0);
410 }
411
412 //give the tool a short time to get all the messages and then reply with a disconnect
413 start_time = GetOSCR0();
414 while(pISR->DisconnectReceived == FALSE)
415 {
416 //if a download is waiting, terminate it and break out of loop: wtptp tool quits on a NACK
417 if(pISR->DLWaiting == TRUE)
418 {
419 SendError(UnknownImageError);
420 break;
421 }
422
423 if(OSCR0IntervalInSec(start_time, GetOSCR0()) > PM_DISCONNET_MS)
424 break;
425 }
426
427 //lastly, reply with an ACK
428 if(pISR->DisconnectReceived == TRUE)
429 SendAck();
430
431 //need to release PM semaphore and reset all flags!
432 //Semaphore_Release(PROTOCOL_semaphore);
433 memset(pISR, 0, sizeof(ProtocolISR));
434
435 return NoError;
436}
437
438/* InitPort()
439 *
440 * Call into the driver to setup the ports and enable interrupts
441 *
442 */
443UINT_T InitPort(UINT_T port)
444{
445 return USBAPI_InitializeDevice(port);
446}
447
448UINT ImageDownloadWaiting(UINT_T media_num)
449{
450 pProtocolISR pISR = getProtocolISR();
451
452 //check to see if a USB is linked and said linked USB is the matching one
453 // if so, return whether a GetVersion request was made (i.e. a download is waiting)
454 if( (pISR->plinkedUSB != NULL) &&
455 (pISR->plinkedUSB->bootNum == media_num) )
456 return pISR->DLWaiting;
457 else
458 return FALSE;
459}
460
461
462UINT PreambleReceived()
463{
464 return getProtocolISR()->PreambleReceived;
465}
466
467void ClearPreambleReceived()
468{
469 getProtocolISR()->PreambleReceived = FALSE;
470}
471
472// ShutdownPorts: shutdown all ports
473void ShutdownPorts ()
474{
475 //call into USB API to shutdown all enabled USB devices
476 USBAPI_ShutdownAll();
477}
478
479//Protocol Manager ISR
480// There are three possible scenarios when this routine is called:
481// 1. PM is already used by another USB device (unusual scenario)
482// 2. PM is being used by the calling device (most likely scenario)
483// 3. PM is free (starting scenario)
484// The numbered comments in this routine will match up to the three mentioned scenarios
485void PM_ISR(P_USBAPI_T this, UINT bytes, UINT * buffer)
486{
487 UINT next_size, dummy = NULL;
488 pProtocolISR pISR = getProtocolISR();
489
490 //1. Is someone else using the protocol?
491 if( (pISR->plinkedUSB != this) && (pISR->plinkedUSB != NULL) )
492 { //Yes. Another USB is using protocol. Transmit a NAK
493 this->USB_Send(&dummy, PREAMBLE_SIZE, this);
494 //reprime so it will try again later
495 this->USB_Receive(buffer, PREAMBLE_SIZE, this);
496 //time to leave
497 return;
498 }
499
500 //2. We're already good friends
501 if(pISR->plinkedUSB == this)
502 {
503 if((bytes == PREAMBLE_SIZE ) && (pISR->PreambleReceived == FALSE))
504 { //check the validity of the preamble
505 if( PM_VerifyPreamble((UCHAR *)buffer) )
506 { //good Preamble!
507 pISR->PreambleReceived = TRUE;
508 // clear out any errors, as a new Preamble mean a new Image DL
509 pISR->ErrorCode = 0;
510 //respond with the preamble
511 SendResponse(preambleString, PREAMBLE_SIZE);
512 //set the pRXBuff to protocol area
513 resetProtoBuff();
514 //Setup for a new CMD
515 this->USB_Receive((UINT *)getProtoBuff(), this->maxpacketsize, this);
516 }
517 else
518 { //bad Preamble!
519 //Transmit a NAK
520 this->USB_Send(&dummy, PREAMBLE_SIZE, this);
521 //Reset USB control to download again
522 this->USB_Receive(buffer, PREAMBLE_SIZE, this);
523 }
524 }
525 else
526 {
527 //4. call into PM handler
528 next_size = PM_Handler(bytes);
529
530 //5. call into USBAPI to set up next RECEIVE
531 this->USB_Receive((UINT *)getProtoBuff(), next_size, this);
532 }
533 //all done, exit now
534 return;
535 }
536
537 //3. Newbie! Must receive a preamble or else we can't be friends.
538 if(pISR->plinkedUSB == NULL)
539 { //check the validity of the preamble
540 if( (bytes == PREAMBLE_SIZE) && PM_VerifyPreamble((UCHAR *)buffer) )
541 { //good Preamble!
542 pISR->PreambleReceived = TRUE;
543 // clear out any errors, as a new Preamble mean a new Image DL
544 pISR->ErrorCode = 0;
545 //Check out using semaphore and store the USB API pointer
546 pISR->plinkedUSB = this;
547 //Semaphore_Acquire(PROTOCOL_semaphore);
548 //respond with the preamble
549 SendResponse(preambleString, PREAMBLE_SIZE);
550 //set the pRXBuff to protocol area
551 resetProtoBuff();
552 //Setup for a new CMD
553 this->USB_Receive((UINT *)getProtoBuff(), this->maxpacketsize, this);
554 }
555 else
556 { //Premable was not valid
557 //Transmit a NAK
558 this->USB_Send(&dummy, PREAMBLE_SIZE, this);
559 //Reset USB control to download again
560 this->USB_Receive(buffer, PREAMBLE_SIZE, this);
561 }
562 return;
563 }
564}
565
566
567// PROTOCOL HANDLER
568// This routine is the singular handler for protocol commands
569// - JTAG over USB (CMD 36)
570// - Image Downloading
571//
572// Inputs:
573// - pUSBhandle: pointer the calling USB handler
574// - packetlength: length of the packet that triggered this call
575// Outputs:
576// - PrimeSize: the size to prime the next input packet for
577UINT PM_Handler(UINT packetLength)
578{
579 pProtocolCmd pCmd;
580 pProtocolISR pISR = getProtocolISR();
581 UINT next_size = pISR->plinkedUSB->maxpacketsize; //defualt is a full packet
582
583 //1st check if a fast download command is in progress
584 if(pISR->FastDLInProgress)
585 {
586 //Update counters
587 pISR->CurrentTransferAddress += packetLength;
588 pISR->DataLeft -= packetLength;
589 pISR->MaxImageSize = (packetLength > pISR->MaxImageSize) ? 0 : (pISR->MaxImageSize - packetLength);
590
591 //When DataLeft = 0, then the command is finally finished. respond back
592 if(pISR->DataLeft == 0)
593 {
594 pISR->FastDLInProgress = 0;
595 HandleDataCmd(); //send the response
596 resetProtoBuff(); //restore the location back to protocol area
597 }
598 else
599 { // Fast Download continues... set up info for next descriprots
600 //security check: can only download "MaxImageSize" per image DL. If malicious software tries to download more,
601 //this line of code will restrict the size dTD and force USB NACKs for any additional data
602 next_size = (pISR->DataLeft > pISR->MaxImageSize) ? pISR->MaxImageSize : pISR->DataLeft;
603 next_size = (next_size < FD_BLOCK_SIZE ) ? next_size : FD_BLOCK_SIZE;
604 setProtoBuff((UINT8 *)pISR->CurrentTransferAddress); //set location for USB to put data
605 }
606 return next_size;
607 }
608
609 //normal commands
610 //Overlay the Command structure over the buffer
611 pCmd = setProtocolCmd(getProtoBuff());
612
613 //All normal commands will load the data to the protocol buffer
614 resetProtoBuff();
615
616 //Sanity check - make sure the size read in matches the size defined in the ProtocolCmd packet
617 //if ( packetLength != (8+pCmd->Length) )
618 //{
619 // pISR->ErrorCode = UnknownProtocolCmd;
620 // SendError(UnknownProtocolCmd);
621 // return next_size;
622 //}
623
624 // update Interrupt Status Flags
625 //pISR->CurrentCommand = pCmd->Command;
626
627 switch( pCmd->Command )
628 {
629 case MessageCmd:
630 //try and send a message
631 // clear the upload command flag for upload
632 pISR->CommandReceived = FALSE;
633 HandleMessageCmd();
634 break;
635 #if !BOOTROM
636 case ProtocolVersionCmd:
637 // Send the major and minor protocol version bacl
638 HandleProtocolVersionCmd();
639 break;
640 case GetParametersCmd:
641 // Send Protocol Parameters to host.
642 HandleGetParametersCmd();
643 break;
644 case GetImageCrcCmd:
645 HandleGetCrcCmd();
646 break;
647 case GetBadBlockCmd:
648 HandleGetBadBlock();
649 break;
650 #endif
651 #if JTAG_OVER_JTAG_SUPPORTED
652 case JtagOverMediaCmd:
653 //copy the JTAG data into the JTAG structure
654 memcpy( (void *)pJTAG_CPCData->CommandFromHost, (void*)&pCmd->Data[0], pCmd->Length);
655 Jtag_Media_Handler();
656 break;
657 #endif
658 case GetVersionCmd:
659 //Indicate that a download is pending, but do NOT respond yet
660 pISR->DLWaiting = TRUE;
661 pISR->CommandReceived = TRUE; // mark it as download command
662 break;
663 case UploadDataHeaderCmd:
664 pISR->DLWaiting = TRUE; // indicate that a upload is pending
665 pISR->CommandReceived = TRUE; // mark it as upload command
666 break;
667 case UploadDataCmd:
668 pISR->CommandReceived = TRUE; // mark it as upload command
669 break;
670 case SelectImageCmd:
671 HandleSelectImageCmd(pISR->CurrentImageID);
672 next_size = 9; //the next command will be larger than normal
673 break;
674 case VerifyImageCmd:
675 HandleVerifyImageCmd();
676 next_size = 12; //the next command will be larger than normal
677 break;
678 case DataHeaderCmd:
679 next_size = HandleDataHeaderCmd();
680 if (pISR->FastDLInProgress) //override the download address for fast download
681 setProtoBuff((UINT8 *)pISR->CurrentTransferAddress); //set location for USB to put data
682 break;
683 case DownloadDataCmd:
684 //Note: this will only be triggered for "slow" download.
685 //move data from the buffer to boot address
686 memcpy((void *)(pISR->CurrentTransferAddress), (void*)&pCmd->Data[0], pCmd->Length);
687 //Update counters
688 pISR->CurrentTransferAddress += pCmd->Length;
689 pISR->MaxImageSize -= (pCmd->Length > pISR->MaxImageSize) ? pISR->MaxImageSize : pCmd->Length;
690 HandleDataCmd();
691 break;
692 case DoneCmd:
693 //Indicate that a download has finished, but do NOT respond yet
694 pISR->DLWaiting = FALSE;
695 pISR->CommandReceived = TRUE; // exit for upload while loop
696 break;
697 case DisconnectCmd:
698 pISR->DisconnectReceived = TRUE;
699 break;
700 default:
701 break;
702 }
703
704
705
706
707
708 return next_size;
709}
710
711
712
713
714
715
716// PM_ReceiveImage()
717//
718// This is the Protocol Recieve image routine. It does the following:
719// 1. Set the parameters for the download:
720// -- destination address
721// -- max size
722// -- image ID
723// 2. Check and wait for a pending image download request (GetVersion command from host)
724// 3. Download will be kicked off by sending the GetVersion response.
725// 4. Wait until the download has finished (DoneCommand will indicate that)
726//
727UINT_T PM_ReceiveImage(UINT_T dummy, UINT_T address, UINT_T size, UINT_T image_id)
728{
729 UINT retval = NoError, start_time, wait_time = 0;
730 //pProtocolCmd pCmd = getProtocolCmd();
731 pProtocolISR pISR = getProtocolISR();
732
733 //1. set up initial DL perameters:
734 pISR->CurrentTransferAddress = address;
735 pISR->MaxImageSize = size;
736 pISR->CurrentImageID = image_id;
737
738 //AddMessageCompound((UINT8_T*) ("*** PM_ReceiveImage pISR->CurrentTransferAddress...\0"), pISR->CurrentTransferAddress);
739
740 do
741 {
742 //2. wait for the download request
743 start_time = GetOSCR0();
744 do
745 { //Check for timeout
746 if( OSCR0IntervalInMilli(start_time, GetOSCR0()) > PM_DL_STARTTIME_MS )
747 {
748 retval = PM_ReceiveTimeOutError_1;
749 break;
750 }
751 }
752 while(pISR->DLWaiting == FALSE);
753
754 //check for an error
755 if(retval != NoError)
756 break;
757
758 //3. send the Get Version response to kick off the download
759 retval = HandleGetVersionCmd();
760
761 //check for an error
762 if(retval != NoError)
763 break;
764
765 /*
766 * Suppose the worst USB transfer speed is 0.5MB/s(in fact, it's about 12MB/s
767 * for HS mode but should also consider FS mode)
768 * Then, the wait time should not exceed (size / 1024 /4) milli seconds.
769 * The extra 2000 ms is to ensure the wait time is none-zero
770 */
771 wait_time = (size >> 9) + 2000;
772
773 //4. Wait for the Image DL to complete or an error
774 start_time = GetOSCR0();
775 do
776 { //Check for timeout
777 if( OSCR0IntervalInMilli(start_time, GetOSCR0()) > wait_time )
778 {
779 retval = PM_ReceiveTimeOutError_2;
780 break;
781 }
782 }
783 while( (pISR->DLWaiting == TRUE) && (pISR->ErrorCode == NoError) );
784
785 }while(FALSE);
786
787 //If there is an protocol error, override local error status
788 if(pISR->ErrorCode)
789 retval = pISR->ErrorCode;
790
791 //clear the flags to indicate an image dl is done
792 pISR->ErrorCode = NoError;
793 pISR->PreambleReceived = FALSE;
794 pISR->DLWaiting = FALSE;
795
796 //finish off the download by sending either the DONE cmd on success or NAK on failure
797 if(retval == PM_ReceiveTimeOutError_1 || retval == PM_ReceiveTimeOutError_2)
798 SendError(retval);
799 else
800 HandleDoneCmd();
801
802 //returns 0 if complete or an error code
803 return retval;
804}
805
806UINT_T GetUploadCommand(void)
807{
808 UINT_T Retval = NoError;
809 UINT_T StartTime;
810
811 pProtocolISR pISR = getProtocolISR();
812
813 StartTime = GetOSCR0(); //Dummy read to flush potentially bad data
814 StartTime = GetOSCR0();
815
816 while(pISR->CommandReceived == FALSE)
817 {
818 Retval = CheckProtocolTimeOut(StartTime);
819 if(Retval != NoError)
820 return Retval;
821 }
822 pISR->CommandReceived = FALSE;
823
824 return Retval;
825}
826
827/*
828 * HandleDownloadFlow()
829 *
830 * This function will handle a upload request unitl it completes or fails
831 * and return the status
832 */
833
834UINT_T HandleUploadFlow(UINT_T address)
835{
836 UINT_T Retval = NoError;
837 pProtocolCmd pCmd = getProtocolCmd();
838 pProtocolISR pISR = getProtocolISR();
839
840 pISR->CurrentTransferAddress = address;
841
842 do{
843 switch(pCmd->Command)
844 {
845 case UploadDataHeaderCmd:
846 Retval = HandleUploadDataHeaderCmd();
847 break;
848 case UploadDataCmd:
849 Retval = HandleUploadDataCmd();
850 break;
851 default:
852 if(pISR->CommandReceived == TRUE)
853 {
854 Retval = SendError(0);
855 Retval = UnknownProtocolCmd;
856 }else
857 Retval = NoError;
858 break;
859 }
860 if(Retval != NoError){
861 break;
862 }
863
864 GetUploadCommand();
865
866 }while (pCmd->Command != DoneCmd);
867
868 return Retval;
869}
870
871/**
872 * Debug Commands
873 **/
874UINT_T HandleUploadDataHeaderCmd(void)
875{
876 UINT_T Retval = NoError;
877 pProtocolCmd pCommand;
878 pProtocolISR pISR;
879 UploadDataParameters uploadParams, *pUploadParams;
880
881#if NAND_CODE || QSPINAND_CODE || SPINAND_CODE
882 UINT_T spare_size, page_size;
883 UINT_T numbers, total_spare_size;
884#endif
885
886
887 pUploadParams = &uploadParams;
888 pCommand = getProtocolCmd();
889 pISR = getProtocolISR();
890 memcpy((void*)pUploadParams,(void*)&pCommand->Data[0],sizeof(UploadDataParameters));
891
892 if (!upload_get_times_flag)
893 {
894 upload_times = pUploadParams->Times; // upload_times >= 1
895
896#if USE_SERIAL_DEBUG
897 obm_printf("upload_times: %d\n\r", upload_times);
898#endif
899
900 ResetUE = pUploadParams->ResetUE;
901 ResetDelay = pUploadParams->ResetTimeDelay;
902
903 obm_printf("ResetUE: %d, ResetDelay: %d\n\r", ResetUE, ResetDelay);
904
905 upload_get_times_flag = 1;
906 }
907
908 // Are the upload parameters ok?
909 Retval = VerifyUploadParameters(pUploadParams);
910 AddMessageError(REPORT_NOTIFICATION, PlatformBusy);
911
912 if(Retval != NoError)
913 {
914 AddMessageError(REPORT_NOTIFICATION, PlatformReady);
915 SendError(Retval);
916 return Retval;
917 }
918 else
919 {
920 getProtocolRsp()->Length = 0;
921 SendAck();
922 }
923
924 // Copy data requested into upload buffer
925
926 //AddMessageError(PlatformBusy);
927 //This could take a while
928
929 if(pUploadParams->Type == UPLOAD_DDR)
930 pISR->CurrentTransferAddress = pUploadParams->Offset;
931 else
932 Retval = CopyUploadDataIntoBuffer(pISR->CurrentTransferAddress, pUploadParams);
933
934 AddMessageError(REPORT_NOTIFICATION, PlatformReady);
935 // data should in buffer now
936
937 if(Retval != NoError)
938 {
939 setProtocolError(Retval);
940 // This was probably an error reading from source as UploadParams checked out ok.
941 // Set to No Error so that error can be sent to Host in HandleUploadDataCmd.
942 Retval = NoError;
943 }
944 else
945 {
946#if NAND_CODE || QSPINAND_CODE || SPINAND_CODE
947 if (upload_nand_spare == TRUE)
948 {
949 spare_size = GetSpareAreaSize(BOOT_FLASH); // get nand spare areas size
950 page_size = GetPageSize(BOOT_FLASH);
951 numbers = pUploadParams->DataSize / page_size; // calculate spare areas number
952 total_spare_size = numbers * spare_size; // total spare size
953
954 pISR->DataLeft = pUploadParams->DataSize + total_spare_size; // data length + total spare length
955 }
956 else
957#endif
958 {
959 pISR->DataLeft = pUploadParams->DataSize;
960 }
961 }
962
963 return Retval;
964
965}
966
967UINT_T HandleUploadDataCmd(void)
968{
969 UINT_T Retval = NoError,txDataSize = 0;
970 pProtocolRsp pRsp = (pProtocolRsp)transmitBuff;
971 pProtocolCmd pCmd = getProtocolCmd();
972 pProtocolISR pISR = getProtocolISR();
973
974 Retval = getProtocolError();
975 if(Retval!= NoError)
976 {
977 // We had a problem reading data for Data Upload
978 SendError(Retval);
979 return Retval;
980 }
981
982 if(pISR->DataLeft <= 0)
983 {
984 Retval = SeqError;
985 SendError(Retval);
986 return Retval;
987 }
988
989 pRsp->Command = UploadDataCmd;
990 pRsp->Sequence = pCmd->Sequence;
991 pRsp->CID = pCmd->CID;
992 pRsp->Status = Ack;
993
994 // Too bad length is only a byte. Not using it.
995 pRsp->Length = 0;
996
997 txDataSize = pISR->DataLeft < UPLOAD_BLOCK_SIZE ? pISR->DataLeft : UPLOAD_BLOCK_SIZE;
998 // Not a fan but have to do this. We have 6 byte status and arbitrary data.
999 memcpy((void*)&pRsp->Data[0], (void*)pISR->CurrentTransferAddress, txDataSize);
1000
1001
1002 // Message bit should NOT be set in flags.
1003 // At this point getProtocolMsg()->MessageFlag will be 0.
1004 pRsp->Flags = pRsp->Flags & ~(MESSAGE_FLAG);
1005 pRsp->Flags = pRsp->Flags | getProtocolMsg()->MessageFlag;
1006
1007 Retval = SendResponse(&pRsp->Command, txDataSize + 6);
1008
1009 pISR->CurrentTransferAddress += txDataSize;
1010 pISR->DataLeft -= txDataSize;
1011
1012 return Retval;
1013}
1014
1015UINT_T CopyUploadDataIntoBuffer(UINT_T address, pUploadDataParameters pUploadParams)
1016{
1017 UINT_T Retval = NoError;
1018
1019 switch(pUploadParams->Type)
1020 {
1021 case UPLOAD_FLASH:
1022 // Fix me. Need code to check if sub type of flash is supported.
1023 if (!upload_config_flash_flag && !FlashInitDone)
1024 {
1025 /* sub type of flash is not supported */
1026 //Retval = PlatformInitFlash(pUploadParams->SubType & 0x1F);
1027 Retval = Configure_Flashes(pUploadParams->SubType & 0x1F, BOOT_FLASH);
1028 if( Retval != NoError)
1029 FatalError(Retval, NULL, NULL);
1030
1031 InitializeFM(LEGACY_METHOD, BOOT_FLASH);
1032
1033 upload_config_flash_flag = 1; // configure flash for upload only one time
1034 }
1035
1036 #if NAND_CODE || QSPINAND_CODE || SPINAND_CODE
1037
1038 #if NAND_CODE
1039 if (pUploadParams->ResetUE == 1)
1040 {
1041 AddMessageError(REPORT_UPLOAD_NOTIFICATION, NandID);
1042 }
1043 #endif
1044
1045 upload_nand_spare = pUploadParams->IncludeOOB;
1046
1047 upload_disable_ecc = pUploadParams->DisableECC;
1048 #endif
1049
1050 // Set the partition.
1051 #if MMC_CODE
1052 SetPartition(pUploadParams->Partition, BOOT_FLASH);
1053 #endif
1054
1055#if defined(NEZHA701) || defined(NEZHA702)
1056 if ((pUploadParams->Offset <= MEP_FALSH_START &&
1057 pUploadParams->Offset + pUploadParams->DataSize > MEP_FALSH_START) ||
1058 (pUploadParams->Offset >= MEP_FALSH_START &&
1059 pUploadParams->Offset < MEP_FALSH_START + MEP_FLASH_LEN))
1060 Retval = NotSupportedError;
1061 else
1062#endif
1063 Retval = ReadFlash(pUploadParams->Offset, address, pUploadParams->DataSize, BOOT_FLASH);
1064 break;
1065 default:
1066 // Not supported.
1067 Retval = NotSupportedError;
1068 break;
1069
1070 }
1071 return Retval;
1072}
1073
1074UINT_T VerifyUploadParameters(pUploadDataParameters pUploadParams)
1075{
1076 UINT_T Retval = NoError, flashNum;
1077 pTIM pTIM_h = GetTimPointer();
1078 switch(pUploadParams->Type)
1079 {
1080 case UPLOAD_FLASH:
1081 // Is flash subtype supported. Looking in Tim.
1082 flashNum = pTIM_h->pConsTIM->FlashInfo.BootFlashSign & 0xFF;
1083 if(flashNum != pUploadParams->SubType & 0xFF &&
1084 flashNum != CI2_USB_D) //Empty board upload
1085 Retval = UnsupportedFlashError;
1086
1087 if(pUploadParams->UploadBypassBBT) {
1088 obm_printf("Upload Flash with BBT bypassed\n\r");
1089 GetFlashProperties(BOOT_FLASH)->FlashSettings.UseBBM = 0;
1090 }
1091 break;
1092 case UPLOAD_DDR:
1093 break;
1094 default:
1095 // Not supported.
1096 Retval = NotSupportedError;
1097 break;
1098
1099 }
1100 return Retval;
1101}
1102
1103UINT_T HandleProtocolVersionCmd()
1104{
1105 UINT_T Retval = 0;
1106 pProtocolRsp pRsp;
1107 pProtocolCmd pCmd;
1108
1109 pCmd = getProtocolCmd();
1110 pRsp = getProtocolRsp();
1111
1112 pRsp->Command = pCmd->Command;
1113 pRsp->Sequence = pCmd->Sequence;
1114 pRsp->CID = pCmd->CID;
1115 pRsp->Status = Ack;
1116 pRsp->Length = 4;
1117
1118 pRsp->Data[0] = COMM_PROTOCOL_MAJOR_VERSION;
1119 pRsp->Data[1] = COMM_PROTOCOL_MINOR_VERSION;
1120 *(UINT16_T*)&pRsp->Data[2] = COMM_PROTOCOL_REV_VERSION;
1121
1122 pRsp->Flags = pRsp->Flags & ~(MESSAGE_FLAG);
1123 pRsp->Flags = pRsp->Flags | getProtocolMsg()->MessageFlag;
1124
1125 SendResponse(&pRsp->Command, 6 + pRsp->Length);
1126 return Retval;
1127}
1128
1129UINT_T HandleGetParametersCmd()
1130{
1131 UINT_T Retval = 0;
1132 pProtocolRsp pRsp;
1133 pProtocolCmd pCmd;
1134
1135 pCmd = getProtocolCmd();
1136 pRsp = getProtocolRsp();
1137
1138 pRsp->Command = pCmd->Command;
1139 pRsp->Sequence = pCmd->Sequence;
1140 pRsp->CID = pCmd->CID;
1141 pRsp->Status = Ack;
1142 // Currently only sending buffer size. But we have 3 more reserved paramters.
1143 // Note: Rsp structure only has space for 12 bytes of data ( 3 params). If we
1144 // are going to use all 4 parameters, we need a buffer and memcpy.
1145 pRsp->Length = 16;
1146
1147 *(UINT16_T *)&pRsp->Data[0] = COMM_PROTOCOL_BUFFER_SIZE & 0xffff;
1148 *(UINT16_T *)&pRsp->Data[2] = (COMM_PROTOCOL_BUFFER_SIZE & 0xffff0000)>> 16;
1149 pRsp->Flags = pRsp->Flags & ~(MESSAGE_FLAG);
1150 pRsp->Flags = pRsp->Flags | getProtocolMsg()->MessageFlag;
1151
1152 // This should be
1153 // SendResponse(&pRsp->Command, 6 + pRsp->Length);
1154 // See note above
1155 SendResponse(&pRsp->Command, 6 + pRsp->Length);
1156 return Retval;
1157}
1158
1159UINT_T HandleGetCrcCmd()
1160{
1161 UINT_T Retval = 0;
1162 pProtocolRsp pRsp = (pProtocolRsp)transmitBuff;
1163 pProtocolCmd pCmd;
1164 UINT_T BufferAddr;
1165 INT_T BufferLen = 4; //Nack
1166
1167 pCmd = getProtocolCmd();
1168
1169 pRsp->Command = pCmd->Command;
1170 pRsp->Sequence = pCmd->Sequence;
1171 pRsp->CID = pCmd->CID;
1172 Retval = GetImageReadBackCrcBuffer(&BufferAddr, &BufferLen);
1173
1174 pRsp->Flags = pRsp->Flags & ~(MESSAGE_FLAG);
1175 pRsp->Flags = pRsp->Flags | getProtocolMsg()->MessageFlag;
1176
1177 if(Retval == NoError){
1178 pRsp->Status = Ack;
1179 //pRsp->Length is UINT8, BufferLen exceed 255
1180 pRsp->Length = BufferLen;
1181 memcpy(&pRsp->Data[0], (UINT8 *)BufferAddr, BufferLen);
1182 }else{
1183 pRsp->Status = Nack;
1184 pRsp->Length = 4;
1185 *(UINT16_T *)&pRsp->Data[0] = Retval & 0xffff;
1186 *(UINT16_T *)&pRsp->Data[2] = (Retval & 0xffff0000)>> 16;
1187 }
1188
1189 //pRsp->Length is UINT8, BufferLen exceed 255, use BufferLen instead
1190 SendResponse(&pRsp->Command, 6 + BufferLen);
1191 return Retval;
1192}
1193
1194UINT_T HandleGetBadBlock()
1195{
1196 UINT_T Retval = 0;
1197 pProtocolRsp pRsp = (pProtocolRsp)transmitBuff;
1198 pProtocolCmd pCmd;
1199 P_FlashProperties_T pFlashProp = GetFlashProperties(BOOT_FLASH);
1200 pBadBlockData bbData;
1201
1202 pCmd = getProtocolCmd();
1203
1204 pRsp->Command = pCmd->Command;
1205 pRsp->Sequence = pCmd->Sequence;
1206 pRsp->CID = pCmd->CID;
1207 pRsp->Status = Ack;
1208
1209 bbData = (pBadBlockData)(&pRsp->Data[0]);
1210 bbData->TotalBadBlocks = GetBadBlockNum();
1211 bbData->TotalBlocks = pFlashProp->NumBlocks;
1212 pRsp->Length = 8;
1213
1214 pRsp->Flags = pRsp->Flags & ~(MESSAGE_FLAG);
1215 pRsp->Flags = pRsp->Flags | getProtocolMsg()->MessageFlag;
1216
1217 SendResponse(&pRsp->Command, 6 + pRsp->Length);
1218 return Retval;
1219}
1220
1221UINT_T AddMessageError(UINT_T ReportType, UINT_T ReportCode)
1222{
1223 UINT_T Retval = 0;
1224
1225 #if VERBOSE_MODE
1226 UINT_T mIndex, i;
1227 pProtocolMsg pMsg = getProtocolMsg();
1228 MessageReport Report;
1229
1230 if(pMsg->NumMessagesQueued == MAXNUMOFMESSAGES)
1231 return MessageBufferFullError; //this is when message buffer is full
1232
1233 //find the next open slot in the Queue
1234 //It will be right after the last good message
1235 //this is a circular queue, so we use the '%' operation
1236 mIndex = (pMsg->CurrentMessageIndex + pMsg->NumMessagesQueued) % MAXNUMOFMESSAGES;
1237
1238 Report.ReportType = ReportType;
1239 Report.Reserved = 0;
1240
1241 for (i = 0; i < 4; i++)
1242 {
1243 Report.ReportCode[i] = (ReportCode >> (8 * i)) & 0xff;
1244 }
1245
1246 // copy message to buffer
1247 pMsg->Lengths[mIndex] = 6;
1248
1249 pMsg->Messages[mIndex][0] = Report.ReportType;
1250 pMsg->Messages[mIndex][1] = Report.Reserved;
1251
1252 for (i = 0; i < 4; i++)
1253 {
1254 pMsg->Messages[mIndex][i + 2] = Report.ReportCode[i];
1255 }
1256
1257 pMsg->MessageType[mIndex] = 1; // Message type 1 indicate report code
1258 //set flag
1259 pMsg->MessageFlag = MESSAGE_FLAG;
1260
1261 pMsg->NumMessagesQueued++;
1262
1263 #endif //endif VERBOSE_MODE
1264 return NoError;
1265}
1266
1267void InitProtocol(void)
1268{
1269 pProtocolMsg pMsg = getProtocolMsg();
1270 //pProtocolCmd pCMD = getProtocolCmd();
1271 pProtocolRsp pRsp = getProtocolRsp();
1272 pProtocolISR pISR = getProtocolISR();
1273
1274 memset(pMsg, 0, sizeof(ProtocolMsg));
1275 //memset(pCMD, 0, sizeof(ProtocolCmd));
1276 memset(pRsp, 0, sizeof(ProtocolRsp));
1277 memset(pISR, 0, sizeof(ProtocolISR));
1278}
1279
1280
1281
1282/*
1283 * HandleRequest()
1284 *
1285 * This is the main function of the protocol manager. It is the entry point
1286 * to start a request over a port after an interrupt is received. The process
1287 * for handling a request is as follows:
1288 *
1289 * 1) Get the preamble from the port and verify it
1290 * 2) Get the first command packet from the port
1291 * 3) Send back and ack with proper flag settings
1292 * 4) Based on the command jump to the download flow or the JTAG flow
1293 * 5) Complete the download or JTAG request and when complete disconnect
1294 * 6) return status to the caller
1295 *
1296 *
1297 */
1298
1299UINT_T HandleRequest(UINT_T src_addr, UINT_T dest_addr, UINT_T max_size, UINT_T image_id)
1300{
1301 UINT_T Retval = NoError;
1302 pProtocolCmd pCmd = getProtocolCmd();
1303
1304 do
1305 {
1306 switch(pCmd->Command)
1307 {
1308 case GetVersionCmd:
1309 //Retval = HandleDownloadFlow(dest_addr, image_id, max_size);
1310 break;
1311
1312#if!BOOTROM
1313 case UploadDataHeaderCmd:
1314 Retval = HandleUploadFlow(src_addr);
1315 if(Retval != NoError)
1316 return Retval;
1317 break;
1318#endif
1319 case DisconnectCmd:
1320 //if there was an issue with a download, then tool will try to disconnect
1321 //handle the disconnect, but return an error since we couldn't do a download
1322 //getProtocolISR()->CommandReceived = TRUE; // This hack is needed for optimization. Handledisconnect waits for a command again
1323 Retval = HandleDisconnect();
1324 return Retval;
1325 default:
1326 //Retval.ErrorCode = SendError(0);
1327 //Retval.ErrorCode = UnknownProtocolCmd;
1328 break;
1329 }
1330 if(Retval != NoError)
1331 break;
1332
1333 }while(pCmd->Command != DoneCmd);
1334
1335 if(pCmd->Command == DoneCmd)
1336 HandleDoneCmd();
1337 else
1338 Retval = SendError(0);
1339
1340 return Retval;
1341}
1342
1343//--------------------------------------------------------
1344// Utility routines
1345//--------------------------------------------------------
1346
1347
1348
1349/*
1350 * Verify that the Preamble matches
1351 */
1352UINT8_T PM_VerifyPreamble( UINT8_T *candidateString )
1353{
1354 //Compare the candidate preamble to the defined string
1355 if( 0 == memcmp(candidateString, preambleString, sizeof(preambleString)) )
1356 { //MATCH
1357 //return that all is good
1358 return TRUE;
1359 }
1360 else
1361 { //Bad String
1362 return FALSE;
1363 }
1364}
1365
1366/*
1367 * Check to see if routine has timed out
1368 */
1369UINT8_T CheckProtocolTimeOut(UINT_T StartTime)
1370{
1371 UINT_T WaitTime = 0;
1372 UINT_T CurrentTime;
1373
1374 CurrentTime = GetOSCR0();
1375
1376 WaitTime = OSCR0IntervalInSec(StartTime, CurrentTime); // measure wait time in sec
1377
1378 if (WaitTime >= PROTOCOL_WAITTIME)
1379 return (CheckProtocolTimeOutError);
1380 else return NoError;
1381}
1382