[processor-sdk/pdk.git] / packages / ti / board / utils / uniflash / host / source / ProcessorSDKSerialFlash.cpp
1 /**
2 * \file ProcessorSDKSerialFlash.cpp
3 *
4 * \brief Command Line Application for File Transfer over UART
5 */
6 /*
7 * Copyright (C) 2017-2019 Texas Instruments Incorporated - http://www.ti.com/
8 */
9 /*
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 *
14 * Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 *
17 * Redistributions in binary form must reproduce the above copyright
18 * notice, this list of conditions and the following disclaimer in the
19 * documentation and/or other materials provided with the
20 * distribution.
21 *
22 * Neither the name of Texas Instruments Incorporated nor the names of
23 * its contributors may be used to endorse or promote products derived
24 * from this software without specific prior written permission.
25 *
26 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
27 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
28 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
29 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
30 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
31 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
32 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
33 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
34 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
35 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
36 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37 *
38 */
39 #include "../include/ProcessorSDKSerialFlash.h"
41 #define DEVICE_SUPPORTED 7
42 #define IMAGETYPE_SUPPORTED 5
43 #define BUFF_SIZE 20
44 #define FIND_STRING 2
46 unsigned int baudRate = BAUDRATE_0;
48 int devtype = 0, imgtype = 0, addroff = 0, elen = 0, RBL = 0, FW = 1, fdesc = 0, flashErase = 0;
49 unsigned int offset = 0, def_elen = 0;
50 char def_itype = '5', def_dtype = '1', def_off = '0';
51 char device_list[DEVICE_SUPPORTED][BUFF_SIZE]={"NAND", "SPI", "QSPI", "OSPI", "eMMC", "HyperFlash", "UFS"};
53 unsigned int standardBaudRate[NUM_OF_SUP_BAUDRATE] = { BAUDRATE_0,
54 BAUDRATE_1,
55 BAUDRATE_2,
56 BAUDRATE_3,
57 BAUDRATE_4,
58 BAUDRATE_5,
59 BAUDRATE_6,
60 BAUDRATE_7,
61 BAUDRATE_8,
62 BAUDRATE_9,
63 BAUDRATE_10,
64 BAUDRATE_11,
65 BAUDRATE_12,
66 BAUDRATE_13
67 #ifdef WINDOWS
68 ,BAUDRATE_14
69 #endif
70 };
72 #ifdef WINDOWS /* Windows APIs */
74 /**
75 * Prints COM port Configuration Parameters.
76 *
77 * \param dcb specifies the control setting for a serial communications device.
78 *
79 * This function prints the COM port parameters like BaudRate, ByteSize, Parity
80 * and StopBits
81 *
82 * \return None.
83 */
85 void PrintCommState(DCB dcb)
86 {
87 /* Print some of the DCB structure values */
88 printf("\nBaudRate = %d, ByteSize = %d, Parity = %d, StopBits = %d\n\n", dcb.BaudRate,
89 dcb.ByteSize,
90 dcb.Parity,
91 dcb.StopBits);
92 }
94 SerialPort::SerialPort() {
95 serialPortHandle = INVALID_HANDLE_VALUE;
96 }
98 SerialPort::~SerialPort() {
99 if (serialPortHandle!=INVALID_HANDLE_VALUE)
100 CloseHandle(serialPortHandle);
101 serialPortHandle = INVALID_HANDLE_VALUE;
102 }
104 /**
105 * Establishes Serial connection with the COM Port
106 *
107 * \param device specifies the COM Port to be connected.
108 *
109 * This function establishes serial connection with the COM Port with the defined
110 * dcb parameters.
111 *
112 * \return Returns 0 on success.
113 */
115 int SerialPort::connect( wchar_t* device, unsigned int baudrate ) {
116 int error=0, buf_siz = 1024;
117 wchar_t append_str[20] = L"\\\\.\\";
118 wchar_t* port_name;
119 DCB dcb = {0};
120 COMMTIMEOUTS timeouts = {0};
121 port_name = wcscat(append_str, device);
123 if(*device == NULL)
124 {
125 cout << "Invalid Device!" << endl;
126 return ERR_INVALID;
127 }
128 serialPortHandle = CreateFileW(port_name, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
129 if (serialPortHandle == INVALID_HANDLE_VALUE)
130 {
131 cout << "Couldn't Open Serial Port!\n";
132 return ERR_INVALID;
133 }
134 dcb.DCBlength = sizeof(DCB);
136 if(!(GetCommState(serialPortHandle, &dcb)))
137 {
138 cout << "GetComm Failed!" << endl;
139 return ERR_COMSTAT;
140 }
142 dcb.BaudRate = baudrate;
143 dcb.Parity = NOPARITY;
144 dcb.StopBits = ONESTOPBIT;
145 dcb.ByteSize = 8;
146 dcb.fParity = 0;
147 dcb.XoffChar = 19;
148 dcb.XonChar = 17;
149 dcb.fOutxCtsFlow = 0;
150 dcb.fOutxDsrFlow = 0;
151 dcb.fDtrControl = 0;
152 dcb.fDsrSensitivity = 0;
153 dcb.fTXContinueOnXoff = 0;
154 dcb.fRtsControl = 0;
155 dcb.XonLim = 0;
156 dcb.XoffLim = 0;
158 #ifdef DEBUG
159 cout << endl << "Configuring COM Port!" << endl;
160 #endif
161 if(!SetCommState(serialPortHandle,&dcb))
162 {
163 error=ERR_COMSTAT;
164 cout << endl << "Configuration Failed!" << endl;
165 }
167 GetCommState(serialPortHandle, &dcb);
168 #ifdef DEBUG
169 PrintCommState(dcb);
170 #endif
171 if(SetupComm(serialPortHandle, buf_siz, buf_siz))
172 {
173 #ifdef DEBUG
174 cout << "Configuring COM Port success!" << endl;
175 #endif
176 }
177 else
178 {
179 cout << "Configuring COM Port failed!" << endl;
180 }
181 #ifdef DEBUG
182 PrintCommState(dcb);
183 #endif
184 if (error!=0) {
185 disconnect();
187 }
188 else {
189 clear();
190 }
191 return error;
192 }
194 /**
195 * Closes the established connection with the COM Port
196 *
197 * \param None
198 *
199 * This function Closes the established connection with the COM Port
200 *
201 * \return None
202 */
204 void SerialPort::disconnect(void) {
205 CloseHandle(serialPortHandle);
206 serialPortHandle = INVALID_HANDLE_VALUE;
207 }
209 int SerialPort::sendArray(unsigned char *buffer, int len) {
210 unsigned long result =0U;
211 if(len <= 0)
212 {
213 cout << "Read Length cannot be 0!" << endl;
214 return ERR_INVALID;
215 }
217 if (serialPortHandle!=INVALID_HANDLE_VALUE)
218 WriteFile(serialPortHandle, buffer, len, (LPDWORD)&result, NULL);
219 else
220 cout << "Invalid Handle!!" << endl;
221 return result;
222 }
224 /**
225 * Reads the COM port
226 *
227 * \param buffer points to the buffer to store the input data
228 * \param len specifies the length of the input data
229 *
230 * This function receives input over the COM port.
231 *
232 * \return Returns the length of the data received.
233 */
235 int SerialPort::getArray (unsigned char *buffer, int len) {
236 unsigned long read_nbr;
237 DWORD dwRead;
238 OVERLAPPED osReader = {0};
239 BOOL fWaitingOnRead = FALSE;
240 read_nbr = 0;
242 if( len <= 0 )
243 {
244 cout << "SerialPortGet: Invalid input parameters!" << len << endl;
245 return ERR_INVALID;
246 }
248 if (!fWaitingOnRead) {
249 /* Issue read operation */
250 if (!ReadFile(serialPortHandle, buffer, len, &dwRead, &osReader)) {
251 if (GetLastError() != ERROR_IO_PENDING)
252 /* Error in communications */
253 cout <<"Error in reading!!" << endl;
254 else
255 fWaitingOnRead = TRUE;
256 }
257 }
258 return((int) dwRead);
259 }
261 /**
262 * Terminates pending read or write operations
263 *
264 * \param None
265 *
266 * This function Discards all characters from the output or input
267 * buffer on the Serial Port
268 *
269 * \return None.
270 */
272 void SerialPort::clear() {
273 PurgeComm (serialPortHandle, PURGE_RXCLEAR | PURGE_TXCLEAR);
274 }
276 /**
277 * Opens the source file
278 *
279 * \param fname points to the absolute path to the file
280 * \param fsize points to the size of the file
281 *
282 * This function opens the source file to be transferred over
283 * COM Port
284 *
285 * \return Returns the handle to the file.
286 */
288 ifstream file_open( char *fname, int *fsize)
289 {
290 ifstream ifile;
292 #ifdef DEBUG
293 cout << endl << "Opening file " << fname << endl;
294 #endif
295 ifile.open(fname, ios::binary); /* Open the file to be transfered */
296 if(!ifile)
297 {
298 cout<<"Error in opening file..!!";
299 exit(0);
300 }
302 ifile.seekg (0, ifile.end);
303 *fsize = ifile.tellg();
304 ifile.seekg (0, ifile.beg);
305 return ifile;
306 }
308 #else /* Linux APIs */
310 FILE *file;
312 /**
313 * Serial Port Setup
314 *
315 * \param fd points to the file descriptor of the Serial Port
316 * \param speed specifies the Bps of the Serial Port
317 * \param parity specifies the Parity of the Serial Port
318 *
319 * This function configures the Serial Port with given Parameters
320 *
321 * \return Returns 0 on success and error value on failure.
322 */
324 int set_interface_attribs (int fd, int speed, int parity)
325 {
326 int error = 0;
327 struct termios tty;
328 memset (&tty, 0, sizeof(tty));
329 if (tcgetattr (fd, &tty) != 0)
330 {
331 cout << "Error " << strerror(errno) << "from tcgetattr\n";
332 error = errno;
333 return error;
334 }
336 cfsetospeed (&tty, speed);
337 cfsetispeed (&tty, speed);
339 tty.c_cflag = (tty.c_cflag & ~CSIZE) | CS8; /* 8-bit chars */
340 tty.c_iflag &= ~(IXON | IXOFF | IXANY); /* shut off xon/xoff ctrl */
341 tty.c_cflag &= ~(PARENB | PARODD); /* shut off parity */
342 tty.c_cflag |= parity;
343 tty.c_cflag &= ~CSTOPB;
344 tty.c_cflag &= ~CRTSCTS;
345 tty.c_oflag = 0;
346 tty.c_lflag = 0;
348 if (tcsetattr (fd, TCSANOW, &tty) != 0)
349 {
350 cout << "error " << errno << "from tcsetattr";
351 error = errno;
352 return error;
353 }
354 return error;
355 }
357 /**
358 * Serial Port Read
359 *
360 * \param buff points to the buffer to get the input byte
361 *
362 * This function reads a byte from Serial port
363 *
364 * \return Returns the number of bytes read.
365 *
366 */
368 int readport(char *buff, int fd)
369 {
370 int n;
371 while (1) {
372 n = read(fd, buff, 1);
373 if (n == -1)
374 switch(errno) {
375 case EAGAIN: /* sleep() */
376 continue;
377 default: break;
378 }
379 if (n ==0) break;
380 return n;
381 }
382 }
384 #endif
386 /**
387 * CRC calculation
388 *
389 * \param buf points to the buffer that contains the data
390 * \param len specifies the length of the data
391 *
392 * This function calculates CRC for each and every packet to
393 * be transmitted over the Serial interface.
394 *
395 * \return Returns the calculated CRC value.
396 */
398 unsigned short crc16_ccitt(unsigned char *buf, int len)
399 {
400 int crc;
401 char i;
402 crc = 0;
404 if(len <= 0)
405 {
406 cout <<"Invalid input parameters!\nCRC Calculation Fails!\n";
407 return ERR_INVALID;
408 }
409 while (--len >= 0)
410 {
411 crc = crc ^ (int) *buf++ << 8;
412 i = 8;
413 do
414 {
415 if (crc & 0x8000)
416 crc = crc << 1 ^ 0x1021;
417 else
418 crc = crc << 1;
419 } while(--i);
420 }
421 return (crc);
422 }
424 #ifdef WINDOWS
425 /**
426 * Xmodem File Transmit
427 *
428 * \param destname points to the COM Port to be connected
429 * \param sname points to the file to be transferred over the COM port
430 *
431 * This function Transfers the file over UART using XMODEM protocol
432 *
433 * \return Returns 0 on success and error value on failure.
434 *
435 */
437 int xmodemFTransfer( wchar_t *destname, char *sname)
438 {
439 SerialPort serialPort;
440 ifstream ifile;
441 unsigned char rxBuff[1];
442 #else
443 /**
444 * Xmodem Transmit
445 *
446 * \param destname points to the COM Port to be connected
447 * \param sname points to the file to be transferred over the COM port
448 *
449 * This function Transfers the file over UART using XMODEM protocol
450 *
451 * \return Returns 0 on success and error value on failure.
452 *
453 */
455 int xmodemFTransfer( char *sname, int fd )
456 {
457 char rxBuff[1];
458 #endif
459 unsigned char txBuff[1030], src[1030], packetno = 1, ack = ACK, EoT = EOT;
460 int i = 0, c =0, ret = 0, len = 0, retry = 0, bufsz = 1, crc = -1, error = 0, ktbytes = 1024, tbytes = 128;
461 int srcsz = 0, maxretry = 25, inbyte = 1, txretry =16, eotretry = 20;
462 #ifdef WINDOWS
463 if((*destname || *sname ) == NULL)
464 {
465 cout << "xmodemFTransfer: Invalid input parameters!" << endl;
466 serialPort.clear();
467 serialPort.disconnect();
468 return ERR_INVALID;
469 }
471 ifile = file_open( sname, &srcsz); /* Opening Binary file to be copied */
472 error = serialPort.connect(destname, baudRate);
473 if(error < 0)
474 return error;
475 #else
477 /* Opening Binary file to be copied */
478 file = fopen(sname, "rb");
479 fseek(file, 0, SEEK_END);
480 srcsz = ftell(file);
481 fseek(file, 0, SEEK_SET);
482 #endif
483 #ifdef DEBUG
484 cout << "\nFile size " << srcsz << "bytes\n";
485 #endif
487 for(;;) {
488 for( retry = 0; retry < txretry; ++retry) {
489 #ifdef WINDOWS
490 if ((serialPort.getArray(rxBuff, inbyte)) == inbyte) {
491 #else
492 if ( readport(&rxBuff[0], fd) == inbyte ) {
493 #endif
494 switch (rxBuff[0]) {
495 case 'C':
496 if( FW == 1 )
497 cout << "\nFlashing Image of size " << srcsz << " bytes\n";
498 else
499 cout << "\nTransferring File of size " << srcsz << " bytes\n";
500 crc = 1;
501 goto start_trans;
502 case NAK:
503 #ifdef DEBUG
504 cout << "In case NAK\n";
505 #endif
506 crc = 0;
507 goto start_trans;
508 case CAN:
509 #ifdef DEBUG
510 cout << "In case CAN\n";
511 #endif
512 #ifdef WINDOWS
513 if( serialPort.getArray(rxBuff, inbyte) == inbyte)
514 #else
515 if( (readport(rxBuff, fd)) == inbyte)
516 #endif
517 {
518 if (rxBuff[0] == CAN) {
519 #ifdef WINDOWS
520 if( (serialPort.sendArray(&ack, inbyte)) && (serialPort.sendArray(&ack, inbyte)) == inbyte )
521 #else
522 if( ((write(fd, &ack, inbyte)) && (write(fd, &ack, inbyte))) == inbyte )
523 #endif
524 cout << "Failure: Canceled by remote !!\n";
525 else
526 cout << " Sending ACK Failed!!\n";
527 #ifdef WINDOWS
528 ifile.close();
529 serialPort.clear();
530 serialPort.disconnect();
531 #endif
532 error = ERR_RCAN; /* canceled by remote */
533 return error;
534 }
535 }
536 break;
537 default:
538 #ifdef DEBUG
539 cout << "In Default" << rxBuff[0] << endl;
540 #endif
541 break;
542 }
543 }
544 }
545 cout << "\nFailure:Unknown response from target! ";
546 #ifdef WINDOWS
547 if( ((serialPort.sendArray(&ack, inbyte)) && (serialPort.sendArray(&ack, inbyte)) && (serialPort.sendArray(&ack, inbyte))) == inbyte )
548 #else
549 if( ((write(fd, &ack, inbyte)) && (write(fd, &ack, inbyte)) && (write(fd, &ack, inbyte))) == inbyte )
550 #endif
551 cout << "Please check the connection!\n";
552 else
553 cout << "Sending ACK Failed!!\n";
554 error = ERR_NOSYNC; /* no sync */
555 #ifdef WINDOWS
556 ifile.close();
557 serialPort.clear();
558 serialPort.disconnect();
559 #else
560 fclose(file);
561 #endif
562 return error;
564 for(;;) {
565 start_trans:
566 txBuff[0] = STX; bufsz = ktbytes;
567 txBuff[1] = packetno;
568 txBuff[2] = ~packetno;
569 c = srcsz - len;
570 if (c > bufsz) c = bufsz;
571 #ifdef WINDOWS
572 ifile.read((char*)src,c);
573 #else
574 fread(src, inbyte, c, file);
575 #endif
576 if (c >= 0) {
577 memset (&txBuff[3], 0, bufsz);
578 if (c == 0) {
579 txBuff[3] = CTRLZ;
580 }
581 else {
582 cout <<((len*100)/srcsz) <<"% complete\r";
583 #ifndef windows
584 fflush(stdout);
585 #endif
586 memcpy (&txBuff[3], &src[0], c);
587 if (c < bufsz) txBuff[3+c] = 26;
588 }
589 if (crc) {
590 unsigned short ccrc = crc16_ccitt(&txBuff[3], bufsz);
591 if( crc < 0 )
592 {
593 #ifdef WINDOWS
594 ifile.close();
595 serialPort.clear();
596 serialPort.disconnect();
597 #else
598 fclose(file);
599 #endif
600 return crc;
601 }
602 txBuff[bufsz+3] = (ccrc>>8) & 0xFF;
603 txBuff[bufsz+4] = ccrc & 0xFF;
604 }
605 else {
606 unsigned char ccks = 0;
607 for (i = 3; i < bufsz+3; ++i) {
608 ccks += txBuff[i];
609 }
610 txBuff[bufsz+3] = ccks;
611 }
612 for (retry = 0; retry < maxretry; ++retry) {
613 #ifdef WINDOWS
614 if(serialPort.sendArray(&txBuff[i], bufsz+4+(crc?1:0)) != bufsz+4+(crc?1:0)) //Check this
615 #else
616 if(write(fd, &txBuff[i], bufsz+4+(crc?1:0)) != bufsz+4+(crc?1:0))
617 #endif
618 {
619 cout <<endl << "Transmit Failed at " << len+i << " byte" <<endl;
620 #ifdef WINDOWS
621 ifile.close();
622 serialPort.clear();
623 serialPort.disconnect();
624 #else
625 fclose(file);
626 #endif
627 error = ERR_XMIT;
628 return error;
629 }
630 #ifdef WINDOWS
631 if ((serialPort.getArray(rxBuff, inbyte)) == inbyte ) {
632 #else
633 if ( (readport(rxBuff, fd)) == inbyte ) {
634 #endif
635 #ifdef DEBUG
636 cout <<endl << "Received from Rx !!" << rxBuff[0] << "Retry" << retry << endl;
637 #endif
638 switch (rxBuff[0]) {
639 case ACK:
640 ++packetno;
641 len += bufsz;
642 goto start_trans;
643 case CAN:
644 #ifdef WINDOWS
645 if( (serialPort.getArray(rxBuff, inbyte)) == inbyte )
646 #else
647 if( (readport(rxBuff, fd) ) == inbyte )
648 #endif
649 {
650 if (rxBuff[0] == CAN) {
651 #ifdef WINDOWS
652 if (serialPort.sendArray(&ack, inbyte) != inbyte)
653 #else
654 if (write(fd, &ack, inbyte) != inbyte)
655 #endif
656 cout << "Sending ACK Failed!!\n";
657 cout << "\nFailure: Canceled by remote!!\n";
658 #ifdef WINDOWS
659 ifile.close();
660 serialPort.clear();
661 serialPort.disconnect();
662 #else
663 fclose(file);
664 #endif
665 error = ERR_RCAN;
666 return error; /* canceled by remote */
667 }
668 }
669 break;
670 case FLASH_FAILURE:
671 cout << "\nFlash Programming Failed!!\n";
672 #ifdef WINDOWS
673 if (serialPort.sendArray(&ack, inbyte) != inbyte)
674 #else
675 if (write(fd, &ack, inbyte) != inbyte)
676 #endif
677 cout << "\nSending ACK Failed!!\n";
678 goto conn_close;
679 break;
680 case NAK:
681 default:
682 break;
683 }
684 }
685 }
686 #ifdef WINDOWS
687 if( ((serialPort.sendArray(&ack, inbyte)) && (serialPort.sendArray(&ack, inbyte)) && (serialPort.sendArray(&ack, inbyte))) == inbyte )
688 #else
689 if( ((write(fd, &ack, inbyte)) && (write(fd, &ack, inbyte)) && (write(fd, &ack, inbyte))) == inbyte )
690 #endif
691 cout << "Failure: Transmit Error!!\n";
692 else
693 cout << "Sending ACK Failed!!\n";
694 #ifdef WINDOWS
695 ifile.close();
696 serialPort.clear();
697 serialPort.disconnect();
698 #else
699 fclose(file);
700 #endif
701 error = ERR_XMIT;
702 return error; /* xmit error */
703 }
704 else {
705 error = 0;
706 for (retry = 0; retry < eotretry; ++retry) {
707 #ifdef DEBUG
708 cout << "Sending EOT\n";
709 #endif
710 #ifdef WINDOWS
711 if (serialPort.sendArray(&EoT, inbyte) != inbyte)
712 #else
713 if (write(fd, &EoT, inbyte) != inbyte)
714 #endif
715 cout << "Sending EOT Failed!!\n";
716 #ifdef WINDOWS
717 if (serialPort.getArray(rxBuff, inbyte) != inbyte)
718 #else
719 if ( (readport(rxBuff, fd)) != inbyte)
720 #endif
721 cout << "ACK not received for EOT!!\n";
722 if ( rxBuff[0] == ack)
723 {
724 #ifdef DEBUG
725 {cout << "Rcvd ACK for EOT\n"; }
726 #endif
727 if( FW == 0 )
728 cout <<"File Transfer complete!\n";
729 }
730 break;
731 }
732 if( FW == 1 )
733 {
734 for(;;)
735 {
736 #ifdef WINDOWS
737 if (serialPort.getArray(rxBuff, inbyte) != inbyte)
738 #else
739 if ( (readport(rxBuff, fd)) != inbyte)
740 #endif
741 {
742 cout << "Read Failure!!\n";
743 }
744 if ( rxBuff[0] == FLASH_SUCCESS)
745 {
746 cout << "\rFlash Programming Success!";
747 cout << "\n";
748 rxBuff[0] = ack;
749 #ifdef WINDOWS
750 if (serialPort.sendArray(&ack, inbyte) != inbyte)
751 #else
752 if (write(fd, &ack, inbyte) != inbyte)
753 #endif
754 cout << "\nSending SPI ACK Failed!!\n";
755 goto conn_close;
756 }
757 else if ( rxBuff[0] == FLASH_FAILURE)
758 {
759 cout << "\nFlash Programming Failed!!\n";
760 #ifdef WINDOWS
761 if (serialPort.sendArray(&ack, inbyte) != inbyte)
762 #else
763 if (write(fd, &ack, inbyte) != inbyte)
764 #endif
765 cout << "\nSending ACK Failed!!\n";
766 goto conn_close;
767 }
768 }
769 }
770 goto conn_close;
771 conn_close:
772 #ifdef WINDOWS
773 ifile.close();
774 serialPort.clear();
775 serialPort.disconnect();
776 #else
777 fclose(file);
778 #endif
779 error = (rxBuff[0] == ack)?0:ERR_NOACK;
780 break;
781 }
782 }
783 break;
784 }
785 return error;
786 }
788 #ifdef WINDOWS
789 /**
790 * Xmodem Baudrate change
791 *
792 * \param destname points to the COM Port to be connected
793 *
794 * This function request a baudrate change over UART using XMODEM protocol.
795 *
796 * \return Returns 0 on success and error value on failure.
797 *
798 */
799 int getMaxBaudRate( wchar_t *destname, unsigned char *maxBaudrate )
800 {
801 SerialPort serialPort;
802 unsigned char rxBuff[1];
803 #else
804 /**
805 * Xmodem Header Transmit
806 *
807 * This function request a baudrate change over UART using XMODEM protocol.
808 *
809 * \return Returns 0 on success and error value on failure.
810 *
811 */
812 int getMaxBaudRate( int fd, unsigned char *maxBaudrate )
813 {
814 char rxBuff[1];
815 #endif
816 unsigned char ack = ACK, EoT = EOT, nSupported = NOT_SUPPORTED_BAUDRATE;
817 int error = 0, inbyte = 1, crc = 0, hsize = 12;
818 unsigned short ccrc;
819 unsigned char command[14];
820 const char start = 'S', getCmd = GET_MAX_BAUDRATE_CMD;
821 unsigned short i;
823 #ifdef WINDOWS
824 if((*destname) == NULL)
825 {
826 cout << "xmodemHTransfer: Invalid input parameters!" << endl;
827 return ERR_INVALID;
828 }
829 error = serialPort.connect(destname, BAUDRATE_0);
830 if(error < 0)
831 return error;
832 #endif
834 memset (command, 0, sizeof(command));
835 memcpy (command, &start, 1);
836 memcpy (&command[1], &getCmd, 1);
838 for (;;){
839 #ifdef WINDOWS
840 if ((serialPort.getArray(rxBuff, inbyte)) == inbyte)
841 #else
842 if ((readport(rxBuff, fd)) == inbyte)
843 #endif
844 {
845 if (rxBuff[0] == 'C') {
846 crc = 1;
847 ccrc = crc16_ccitt(command, hsize);
848 #ifdef DEBUG
849 cout <<"crc: " <<ccrc <<endl;
850 #endif
851 command[hsize] = (ccrc>>8) & 0xFF;
852 command[hsize+1] = ccrc & 0xFF;
854 #ifdef DEBUG
855 cout <<"hsize: " <<hsize <<endl;
856 #endif
857 #ifdef WINDOWS
858 if(serialPort.sendArray(command, (hsize+2)) != (hsize+2))
859 #else
860 if(write(fd, command, (hsize+2)) != (hsize+2))
861 #endif
862 {
863 cout << "Transmit of header Failed!\n";
864 error = ERR_XMIT;
865 #ifdef WINDOWS
866 serialPort.clear();
867 serialPort.disconnect();
868 #endif
869 return error;
870 }
871 else
872 {
873 #ifdef WINDOWS
874 if ((serialPort.getArray(rxBuff, inbyte)) != inbyte )
875 #else
876 if ( (readport(rxBuff, fd)) != inbyte )
877 #endif
878 {
879 #ifdef DEBUG
880 cout << "Received from Rx !!" << rxBuff[0] << "Retry" << retry << endl;
881 #endif
882 }
883 else {
884 if (rxBuff[0] == ACK)
885 {
886 for (i=0; i<2; i++) { //Maximum supported baudrate can be get maximum of 2 times
887 #ifdef WINDOWS
888 if ((serialPort.getArray(rxBuff, inbyte)) != inbyte)
889 #else
890 if ((readport(rxBuff, fd)) != inbyte)
891 #endif
892 {
893 error = ERR_XMIT;
894 #ifdef WINDOWS
895 serialPort.clear();
896 serialPort.disconnect();
897 #endif
898 return error;
899 }
900 else
901 {
902 /* Currently, BAUDRATE_6000000 is the maximum supported baudrate supported */
903 if (rxBuff[0] <= BAUDRATE_6000000)
904 {
905 if (rxBuff[0] <= MAX_SUPPORTED_BAUDRATE)
906 break;
907 else
908 {
909 #ifdef WINDOWS
910 if (serialPort.sendArray(&nSupported, inbyte) != inbyte)
911 #else
912 if ( write(fd, &nSupported, inbyte)!= inbyte )
913 #endif
914 {
915 cout << "Failure in transmission" << endl;
916 #ifdef WINDOWS
917 serialPort.clear();
918 serialPort.disconnect();
919 #endif
920 error = ERR_XMIT;
921 return error;
922 }
923 }
924 }
925 else
926 {
927 #ifdef WINDOWS
928 if( (serialPort.getArray(rxBuff, inbyte)) == inbyte )
929 #else
930 if( readport(rxBuff, fd) == inbyte )
931 #endif
932 {
933 if (rxBuff[0] == CAN) {
934 #ifdef WINDOWS
935 if (serialPort.sendArray(&ack, inbyte) != inbyte)
936 #else
937 if ( write(fd, &ack, inbyte)!= inbyte )
938 #endif
939 cout <<"Sending ACK Failed!!\n";
940 cout <<"\nFailure: Canceled by remote!!\n";
941 error = ERR_RCAN;
942 #ifdef WINDOWS
943 serialPort.clear();
944 serialPort.disconnect();
945 #endif
946 return error; /* canceled by remote */
947 }
948 }
949 }
950 }
951 }
953 if (i < 2) { //checks whether a valid baudrate received within 2times
954 *maxBaudrate = rxBuff[0];
955 #ifdef WINDOWS
956 if (serialPort.sendArray(&ack, inbyte) != inbyte)
957 #else
958 if ( write(fd, &ack, inbyte) != inbyte )
959 #endif
960 cout << "Sending ACK Failed!!\n";
961 #ifdef WINDOWS
962 if (serialPort.sendArray(&EoT, inbyte) != inbyte)
963 #else
964 if ( write(fd, &EoT, inbyte) != inbyte )
965 #endif
966 cout <<"Sending EOT Failed!!\n";
967 #ifdef WINDOWS
968 if (serialPort.getArray(rxBuff, inbyte) != inbyte)
969 #else
970 if (readport(rxBuff, fd) != inbyte)
971 #endif
972 {
973 cout << "ACK not received for EOT!!\n";
974 error = ERR_XMIT;
975 #ifdef WINDOWS
976 serialPort.clear();
977 serialPort.disconnect();
978 #endif
979 return error;
980 }
981 else if (rxBuff[0] != ack)
982 {
983 error = ERR_RCAN;
984 #ifdef WINDOWS
985 serialPort.clear();
986 serialPort.disconnect();
987 #endif
988 return error; /* canceled by remote */
989 }
990 else
991 {
992 return error;
993 }
994 }
995 else //else if CAN
996 {
997 #ifdef WINDOWS
998 if( (serialPort.getArray(rxBuff, inbyte)) == inbyte )
999 #else
1000 if( readport(rxBuff, fd) == inbyte )
1001 #endif
1002 {
1003 if (rxBuff[0] == CAN) {
1004 #ifdef WINDOWS
1005 if (serialPort.sendArray(&ack, inbyte) != inbyte)
1006 #else
1007 if ( write(fd, &ack, inbyte)!= inbyte )
1008 #endif
1009 cout <<"Sending ACK Failed!!\n";
1010 cout <<"\nFailure: Canceled by remote!!\n";
1011 error = ERR_RCAN;
1012 #ifdef WINDOWS
1013 serialPort.clear();
1014 serialPort.disconnect();
1015 #endif
1016 return error; /* canceled by remote */
1017 }
1018 }
1019 }
1020 }
1021 else{
1022 #ifdef WINDOWS
1023 if( (serialPort.getArray(rxBuff, inbyte)) == inbyte )
1024 #else
1025 if( readport(rxBuff, fd) == inbyte )
1026 #endif
1027 {
1028 if (rxBuff[0] == CAN) {
1029 #ifdef WINDOWS
1030 if (serialPort.sendArray(&ack, inbyte) != inbyte)
1031 #else
1032 if ( write(fd, &ack, inbyte)!= inbyte )
1033 #endif
1034 cout <<"Sending ACK Failed!!\n";
1035 cout <<"\nFailure: Canceled by remote!!\n";
1036 error = ERR_RCAN;
1037 #ifdef WINDOWS
1038 serialPort.clear();
1039 serialPort.disconnect();
1040 #endif
1041 return error; /* canceled by remote */
1042 }
1043 }
1044 }
1045 }
1046 }
1047 }
1048 }
1049 else
1050 {
1051 #ifdef DEBUG
1052 cout << "Failure in sending Command packet" << endl;
1053 #endif
1055 }
1056 }
1058 #ifdef WINDOWS
1059 serialPort.clear();
1060 serialPort.disconnect();
1061 #endif
1062 return error;
1063 }
1065 #ifdef WINDOWS
1067 /**
1068 * Xmodem Header Transmit
1069 *
1070 * \param destname points to the COM Port to be connected
1071 * \param sname points to the Header packet to be transferred over the COM port
1072 *
1073 * This function Transfers the Header over UART using XMODEM protocol.
1074 * The Header contains information about the file to be tranfered to the Flash Writer
1075 * program
1076 *
1077 * \return Returns 0 on success and error value on failure.
1078 *
1079 */
1081 int xmodemHTransfer( wchar_t *destname, unsigned char *src)
1082 {
1083 SerialPort serialPort;
1084 unsigned char rxBuff[1], ack = ACK, EoT = EOT;
1086 #else
1087 /**
1088 * Xmodem Header Transmit
1089 *
1090 * \param src points to the Header packet to be transferred over the COM port
1091 *
1092 * This function Transfers the Header over UART using XMODEM protocol.
1093 * The Header contains information about the file to be tranfered to the Flash Writer
1094 * program
1095 *
1096 * \return Returns 0 on success and error value on failure.
1097 *
1098 */
1099 int xmodemHTransfer( unsigned char *src, int fd )
1100 {
1101 char rxBuff[1], ack = ACK, EoT = EOT;
1102 #endif
1103 int error = 0, retry = 0, txretry = 16, inbyte = 1, srcsz = 0, crc = 0, hsize = 12;
1104 unsigned short ccrc;
1105 #ifdef WINDOWS
1106 if((*destname || *src ) == NULL)
1107 {
1108 cout << "xmodemHTransfer: Invalid input parameters!" << endl;
1109 return ERR_INVALID;
1110 }
1111 error = serialPort.connect(destname, BAUDRATE_0);
1112 if(error < 0)
1113 return error;
1114 #else
1115 if(!(*src) )
1116 {
1117 cout << "xmodemHTransfer: Invalid input parameters!" << endl;
1118 return ERR_INVALID;
1119 }
1120 #endif
1122 for(;;) {
1123 #ifdef WINDOWS
1124 if ((serialPort.getArray(rxBuff, inbyte)) == inbyte) {
1125 #else
1126 if ( (readport(rxBuff, fd)) == inbyte ) {
1127 #endif
1128 switch (rxBuff[0]) {
1129 case 'C':
1130 crc = 1;
1131 ccrc = crc16_ccitt(src, hsize);
1132 #ifdef DEBUG
1133 cout <<"crc: " <<ccrc <<endl;
1134 #endif
1135 src[hsize] = (ccrc>>8) & 0xFF;
1136 src[hsize+1] = ccrc & 0xFF;
1138 #ifdef DEBUG
1139 cout <<"hsize: " <<hsize <<endl;
1140 #endif
1141 #ifdef WINDOWS
1142 if(serialPort.sendArray(src, (hsize+2)) != (hsize+2))
1143 #else
1144 if(write(fd, src, (hsize+2)) != (hsize+2))
1145 #endif
1146 {
1147 cout << "Transmit of header Failed!\n";
1148 error = ERR_XMIT;
1149 #ifdef WINDOWS
1150 serialPort.clear();
1151 serialPort.disconnect();
1152 #endif
1153 return error;
1154 }
1155 else
1156 {
1157 #ifdef WINDOWS
1158 if ((serialPort.getArray(rxBuff, inbyte)) == inbyte ) {
1159 #else
1160 if ( (readport(rxBuff, fd)) == inbyte ) {
1161 #endif
1162 #ifdef DEBUG
1163 cout << "Received from Rx !!" << rxBuff[0] << "Retry" << retry << endl;
1164 #endif
1165 switch (rxBuff[0]) {
1166 case ACK:
1167 for (retry = 0; retry < txretry; ++retry) {
1168 #ifdef DEBUG
1169 cout << "Sending EOT\n";
1170 #endif
1171 #ifdef WINDOWS
1172 if (serialPort.sendArray(&EoT, inbyte) != inbyte)
1173 #else
1174 if ( write(fd, &EoT, inbyte) != inbyte )
1175 #endif
1176 cout <<"Sending EOT Failed!!\n";
1177 #ifdef WINDOWS
1178 if (serialPort.getArray(rxBuff, inbyte) != inbyte)
1179 #else
1180 if (readport(rxBuff, fd) != inbyte)
1181 #endif
1182 cout << "ACK not received for EOT!!\n";
1183 if ( rxBuff[0] == ack)
1184 #ifdef DEBUG
1185 cout << "Rcvd ACK for EOT\n";
1186 #endif
1187 break;
1188 }
1189 break;
1190 case CAN:
1191 #ifdef WINDOWS
1192 if( (serialPort.getArray(rxBuff, inbyte)) == inbyte )
1193 #else
1194 if( readport(rxBuff, fd) == inbyte )
1195 #endif
1196 {
1197 if (rxBuff[0] == CAN) {
1198 #ifdef WINDOWS
1199 if (serialPort.sendArray(&ack, inbyte) != inbyte)
1200 #else
1201 if ( write(fd, &ack, inbyte)!= inbyte )
1202 #endif
1203 cout <<"Sending ACK Failed!!\n";
1204 cout <<"\nFailure: Canceled by remote!!\n";
1205 error = ERR_RCAN;
1206 #ifdef WINDOWS
1207 serialPort.clear();
1208 serialPort.disconnect();
1209 #endif
1210 return error; /* canceled by remote */
1211 }
1212 }
1213 break;
1214 case NAK:
1215 default:
1216 cout <<"NAK: Transmit of header Failed\n";
1217 error = ERR_XMIT;
1218 break;
1219 }
1220 }
1221 }
1222 break;
1223 default:
1224 #ifdef DEBUG
1225 cout << "In Default" << rxBuff[0] << endl;
1226 #endif
1227 continue;
1228 }
1229 break;
1230 }
1231 }
1232 if(flashErase && (!error))
1233 {
1234 cout << "Header Transfer Complete!!\n";
1235 for(;;) /* Wait for Flash Erase to complete */
1236 {
1237 #ifdef WINDOWS
1238 if (serialPort.getArray(rxBuff, inbyte) != inbyte)
1239 #else
1240 if ( (readport(rxBuff, fd)) != inbyte)
1241 #endif
1242 {
1243 cout << "Read Failure!!\n";
1244 }
1245 if ( rxBuff[0] == FLASH_SUCCESS)
1246 {
1247 cout << "Flash Erase Success!\n";
1248 #ifdef WINDOWS
1249 if (serialPort.sendArray(&ack, inbyte) != inbyte)
1250 #else
1251 if (write(fd, &ack, inbyte) != inbyte)
1252 #endif
1253 cout << "Sending ACK Failed!!\n";
1254 }
1255 else if ( rxBuff[0] == FLASH_FAILURE)
1256 {
1257 cout << "Flash Erase Failed!!\n";
1258 #ifdef WINDOWS
1259 if (serialPort.sendArray(&ack, inbyte) != inbyte)
1260 #else
1261 if (write(fd, &ack, inbyte) != inbyte)
1262 #endif
1263 cout << "Sending ACK Failed!!\n";
1264 }
1265 break;
1266 }
1267 }
1268 #ifdef WINDOWS
1269 serialPort.clear();
1270 serialPort.disconnect();
1271 #endif
1272 return error;
1273 }
1275 /**
1276 * Input Validation
1277 *
1278 * \param argval contains the input argument to be validated
1279 *
1280 * This function checks for the valid Command Line Arguments
1281 *
1282 * \return Returns 0 on success and error value on failure.
1283 *
1284 */
1286 int validate( const char *argval )
1287 {
1288 int error = 0, dtype = 0, itype = 0, erLen = 0;
1289 /* Validate the Command Line Arguments recived */
1290 if( devtype == 1 )
1291 {
1292 dtype = atoi( argval );
1293 if( (dtype<0) || (dtype>=DEVICE_SUPPORTED) || !isdigit((int) (*argval)) )
1294 {
1295 displayVersion();
1296 cout << "Invalid Device Type!!\n";
1297 devtype++;
1298 displayHelp();
1299 }
1300 devtype++;
1301 memcpy(&def_dtype, argval, 1);
1302 }
1303 if( imgtype == 1 )
1304 {
1305 itype = atoi( argval );
1306 if( (itype<0) || (itype>IMAGETYPE_SUPPORTED) || !isdigit((int) (*argval)) )
1307 {
1308 displayVersion();
1309 cout << "Invalid Image Type!!\n";
1310 imgtype++;
1311 displayHelp();
1312 }
1313 imgtype++;
1314 if( itype == 0 )
1315 RBL = 1;
1316 memcpy(&def_itype, argval, 1);
1317 }
1318 if( addroff == 1 )
1319 {
1320 offset = strtol( argval, NULL, 16 );
1321 if( !isxdigit((int)*argval) )
1322 {
1323 displayVersion();
1324 cout << "Invalid Offset Value!!\n";
1325 addroff++;
1326 displayHelp();
1327 }
1328 addroff++;
1329 }
1330 if( elen == 1 )
1331 {
1332 def_elen = strtol( argval, NULL, 16 );
1333 if(!isxdigit((int) (*argval)) )
1334 {
1335 displayVersion();
1336 cout << "Invalid Erase Length!!\n";
1337 elen++;
1338 displayHelp();
1339 }
1340 elen++;
1341 }
1342 return error;
1343 }
1345 /**
1346 * Input Parser
1347 *
1348 * \param cliarg contains the parser command
1349 * \param cliargval contains the input argument to be validated
1350 *
1351 * This function parses the Command Line Argument and validates it
1352 *
1353 * \return Returns 0 on success and error value on failure.
1354 *
1355 */
1357 int chparam( const char *cliarg, const char *cliargval)
1358 {
1359 int err = 0;
1360 #ifdef DEBUG
1361 cout<<"cliarg: " <<cliarg <<endl <<"cliargval :" <<cliargval <<endl;
1362 #endif
1363 if( !(strcmp(cliarg,"-d")) )
1364 {
1365 if( devtype > 0 )
1366 {
1367 displayVersion();
1368 cout <<"\nDuplication of Device Type Detected!!";
1369 err = -1;
1370 return err;
1371 }
1372 else
1373 devtype++;
1374 validate(cliargval);
1375 }
1376 else if( !(strcmp(cliarg,"-i")) )
1377 {
1378 if( imgtype > 0 )
1379 {
1380 displayVersion();
1381 cout <<"\nDuplication of Image Type Detected!!";
1382 err = -1;
1383 return err;
1384 }
1385 else
1386 imgtype++;
1387 validate(cliargval);
1388 }
1389 else if( !(strcmp(cliarg,"-o")) )
1390 {
1391 if( addroff > 0 )
1392 {
1393 displayVersion();
1394 cout <<"\nDuplication of Offset Detected!!";
1395 err = -1;
1396 return err;
1397 }
1398 else
1399 addroff++;
1400 validate(cliargval);
1401 }
1402 else if( !(strcmp(cliarg,"-e")) )
1403 {
1404 if( elen > 0 )
1405 {
1406 displayVersion();
1407 cout <<"\nDuplication of Erase Length Detected!!";
1408 err = -1;
1409 return err;
1410 }
1411 else
1412 elen++;
1413 validate(cliargval);
1414 }
1415 else if( !(strcmp(cliarg,"-f")) )
1416 err = 0;
1417 else
1418 err = -1;
1420 return err;
1421 }
1423 /**
1424 * Serial Port Open
1425 *
1426 * \param comm_port points to the Serial port to be opened
1427 *
1428 * This function opens the Serial port in the given configuration
1429 *
1430 * \return Returns 0 on success and error value on failure.
1431 *
1432 */
1434 #ifndef WINDOWS
1435 int openport(char *comm_port, unsigned int baudrate)
1436 {
1437 int error = 0;
1439 fdesc = open(comm_port, O_RDWR | O_NOCTTY |O_NDELAY );
1440 if (fdesc <0)
1441 {
1442 cout << "Error opening " << comm_port << ": " << strerror(errno);
1443 error = errno;
1444 return error;
1446 }
1448 error = set_interface_attribs(fdesc, baudrate, 0);
1449 return error;
1450 }
1451 #endif
1453 /**
1454 * FlashErase
1455 *
1456 * \param optionNames points to the options available
1457 * \param optionValues points to the values of the options
1458 * \param optionLen points to the number of the options
1459 *
1460 * This function erases the flash memory starting from the
1461 * offset value till the erase length
1462 *
1463 * \return Returns 0 on success and error value on failure.
1464 *
1465 */
1467 int FlashErase( const char** optionNames, const char** optionValues, const int optionLen )
1468 {
1469 const char **commPort, **optInName, **optInVal;
1470 size_t cSize;
1471 wchar_t* wc;
1472 int err = 0, i = 0;
1473 unsigned char header[16];
1474 const char start = 'S', erase = ERASE_CMD;
1476 flashErase++;
1478 for( i = 0; i < (optionLen-2) ; i+=2 )
1479 {
1480 optInName = (&(*optionNames))+i;
1481 optInVal = (&(*optionValues))+i;
1482 if(!(strcmp( *optInName,"-c" )))
1483 {
1484 commPort = optInVal;
1485 }
1486 else
1487 {
1488 if( chparam(*optInName, *optInVal) != 0)
1489 displayHelp();
1490 }
1491 }
1492 #ifdef WINDOWS
1493 cSize = strlen(*commPort)+1;
1494 wc = new wchar_t[cSize];
1495 mbstowcs (wc, *commPort, cSize);
1496 #else
1497 err = openport( (char *)*commPort, baudRate );
1498 if(err == 0)
1499 cout <<"Opening Port Successful!\n";
1500 else
1501 {
1502 cout <<"Opening Port Failed!\n";
1503 return err;
1504 }
1505 #endif
1506 /* Create Header Packet */
1507 memset (header, 0, sizeof(header));
1508 memcpy(header, &start, 1);
1509 memcpy(&header[1], &erase, 1);
1510 memcpy(&header[2], &def_dtype, 1);
1511 memcpy(&header[3], &def_itype, 1);
1512 memcpy(&header[4], &offset, 4);
1513 memcpy(&header[8], &def_elen, 4);
1514 displayVersion();
1515 cout <<"\nErasing Flash....\n";
1517 #ifdef DEBUG
1518 cout <<"Header - " << header << endl;
1519 #endif
1521 cout << "\nTransferring Header information..\n";
1522 #ifdef WINDOWS
1523 err =xmodemHTransfer( wc, header );
1524 #else
1525 err = xmodemHTransfer( header, fdesc );
1526 #endif
1527 if(!err)
1528 {
1529 if(!flashErase)
1530 cout << "Header Transfer Complete!\n";
1531 }
1532 else
1533 #ifndef WINDOWS
1534 close(fdesc);
1535 if(!err)
1536 {
1537 if(!flashErase)
1538 cout << "Header Transfer Complete!\n";
1539 }
1540 else
1541 cout << "Header Transfer Failed!\n";
1542 #endif
1543 return err;
1544 }
1546 /**
1547 * LoadImage
1548 *
1549 * \param imagePath points the path to the image file to be opened
1550 * \param optionNames points to the options available
1551 * \param optionValues points to the values of the options
1552 * \param optionLen points to the number of the options
1553 *
1554 * This function loads the image from the imagePath to the flash device
1555 *
1556 * \return Returns 0 on success and error value on failure.
1557 *
1558 */
1560 int LoadImage( const char * imagePath, const char** optionNames, const char** optionValues, const int optionLen )
1561 {
1562 const char **commPort, **optInName, **optInVal;
1563 size_t cSize;
1564 wchar_t* wc;
1565 int err = 0, i = 0, pathLen = 0;
1566 unsigned char header[16];
1567 unsigned char supBaudRate = 0;
1568 const char start = 'S', program = PROGRAM_CMD, setBaudrate = SET_BAUDRATE_CMD;
1569 std::string sysfw_path;
1570 char findStr[FIND_STRING][BUFF_SIZE]={"am65xx", "j721e"};
1571 char *tokenStr, *tempStr;
1572 char *found = NULL;
1573 std::string fullpath = imagePath;
1574 int beginIdx = fullpath.find_last_of("/\\");
1575 std::string filename = fullpath.substr(beginIdx + 1);
1577 #ifdef DEBUG
1578 if( optionValues == NULL )
1579 cout <<"No option values!\n";
1580 #endif
1581 for( i = 0; i < (optionLen-2) ; i+=2 )
1582 {
1583 optInName = (&(*optionNames))+(i);
1584 optInVal = (&(*optionValues))+(i);
1585 if(!(strcmp( *optInName,"-c" )))
1586 {
1587 commPort = optInVal;
1588 }
1589 else
1590 {
1591 #ifdef DEBUG
1592 cout <<"optInName: " <<*optInName <<endl <<"optInVal: " <<*optInVal <<endl;
1593 #endif
1594 if( chparam(*optInName, *optInVal) != 0)
1595 displayHelp();
1596 }
1597 }
1598 if((RBL == 1) | (optionLen < 6))
1599 {
1600 displayVersion();
1601 cout <<"\nDownloading Flash Programmer..\n";
1602 RBL = 1;
1603 FW = 0;
1604 }
1605 else
1606 {
1607 displayVersion();
1608 FW = 1;
1609 cout <<"\nTransferring the Image to Flash Programmer..\n";
1610 if( addroff == 0 )
1611 offset = strtol( &def_off, NULL, 16 );
1612 }
1613 if (def_itype == '0')
1614 {
1615 for(i=0; i<FIND_STRING; i++)
1616 {
1617 found = strstr((char *)filename.c_str(), findStr[i]);
1618 if(found)
1619 {
1620 break;
1621 }
1622 }
1623 if(found)
1624 {
1625 #ifdef DEBUG
1626 cout <<"\nFinding string: " <<findStr;
1627 cout <<endl <<"Filename=" <<filename <<endl;
1628 #endif
1629 cout <<endl <<"Enabling SysFw transfer!!!\n";
1630 }
1631 }
1632 #ifdef DEBUG
1633 cout <<"Device Type-" << def_dtype << endl <<"ImageType-" << def_itype << endl << "Offset-" << offset << endl;
1634 #endif
1636 #ifdef WINDOWS
1637 cSize = strlen(*commPort)+1;
1638 wc = new wchar_t[cSize];
1639 mbstowcs (wc, *commPort, cSize);
1640 #else
1641 err = openport( (char *)*commPort, baudRate );
1642 if(err == 0)
1643 cout <<"Opening Port Successful!\n";
1644 else
1645 {
1646 cout <<"Opening Port Failed!\n";
1647 return err;
1648 }
1649 #endif
1651 if( RBL ) /* Transfer Flash Writer to RBL */
1652 {
1653 FileTx:
1654 #ifdef WINDOWS
1655 err =xmodemFTransfer( wc, (char *)imagePath);
1656 #else
1657 err =xmodemFTransfer( (char *)imagePath, fdesc );
1658 if(!found)
1659 {
1660 close(fdesc);
1661 }
1662 #endif
1663 /* System Firmware Transfer */
1664 if (found)
1665 {
1666 tokenStr = strtok((char *)imagePath, "/\\");
1667 tempStr = tokenStr;
1668 while (tokenStr != NULL)
1669 {
1670 tokenStr = strtok(NULL, "/\\");
1671 if(tokenStr != NULL)
1672 {
1673 #ifndef WINDOWS
1674 sysfw_path.append("/");
1675 #endif
1676 sysfw_path.append(tempStr);
1677 sysfw_path.append("/");
1678 }
1679 else
1680 {
1681 sysfw_path.append("sysfw.bin");
1682 }
1683 tempStr = tokenStr;
1684 }
1685 #ifdef DEBUG
1686 cout <<endl <<"\nSysfw Filename=" <<sysfw_path <<endl;
1687 #endif
1688 pathLen = sysfw_path.length();
1689 char sysfwPath[pathLen+1];
1690 strcpy(sysfwPath, sysfw_path.c_str());
1692 /* Create Header Packet */
1693 def_itype = FIRMWARE_DEVTYPE; /* Image Type is Firmware */
1694 memset (header, 0, sizeof(header));
1695 memcpy(header, &start, 1);
1696 memcpy(&header[1], &program, 1);
1697 memcpy(&header[3], &def_itype, 1);
1698 #ifdef DEBUG
1699 cout <<"\nSystem Firmware Header - " << header << endl;
1700 #endif
1702 #ifdef WINDOWS
1703 err =xmodemHTransfer( wc, header );
1704 #else
1705 err = xmodemHTransfer( header, fdesc );
1706 #endif
1707 if(!err)
1708 {
1709 cout << "Header Transfer complete\n";
1710 cout << "Transferring System Firmware..";
1711 #ifdef WINDOWS
1712 err =xmodemFTransfer( wc, sysfwPath);
1713 #else
1714 err =xmodemFTransfer( sysfwPath, fdesc );
1715 close(fdesc);
1716 #endif
1717 }
1718 }
1719 return err;
1720 }
1721 else /* Transfer Files to Flash Writer */
1722 {
1723 #ifdef WINDOWS
1724 err = getMaxBaudRate( wc, &supBaudRate );
1725 #else
1726 err = getMaxBaudRate( fdesc, &supBaudRate );
1727 #endif
1728 if(err)
1729 {
1730 #ifndef WINDOWS
1731 close(fdesc);
1732 #endif
1733 cout << "File Transfer Failed!\n";
1734 return err;
1735 }
1737 /* Create Header Packet */
1738 memset (header, 0, sizeof(header));
1739 memcpy(header, &start, 1);
1740 memcpy(&header[1], &setBaudrate, 1);
1741 memcpy(&header[2], &supBaudRate, 1);
1742 #ifdef WINDOWS
1743 err = xmodemHTransfer( wc, header );
1744 #else
1745 err = xmodemHTransfer( header, fdesc );
1746 #endif
1748 #ifdef DEBUG
1749 cout <<"Set BaudRate command packet - " << header << endl;
1750 #endif
1751 if(err)
1752 {
1753 #ifndef WINDOWS
1754 close(fdesc);
1755 #endif
1756 cout << "File Transfer Failed!\n";
1757 return err;
1758 }
1760 /* Create Header Packet */
1761 memset (header, 0, sizeof(header));
1762 memcpy(header, &start, 1);
1763 memcpy(&header[1], &program, 1);
1764 memcpy(&header[2], &def_dtype, 1);
1765 memcpy(&header[3], &def_itype, 1);
1766 memcpy(&header[4], &offset, 4);
1768 cout << "\nTransferring Header Information..\n";
1769 #ifdef DEBUG
1770 cout <<"Header - " << header << endl;
1771 #endif
1773 #ifdef WINDOWS
1774 err = xmodemHTransfer( wc, header );
1775 #else
1776 err = xmodemHTransfer( header, fdesc );
1777 #endif
1778 if(!err)
1779 {
1780 cout << "Header Transfer Complete!\n";
1781 baudRate = standardBaudRate[supBaudRate];
1782 #ifdef DEBUG
1783 cout <<"BaudRate need to change - " << baudRate << endl;
1784 #endif
1785 #ifndef WINDOWS
1786 close(fdesc);
1787 err = openport( (char *)*commPort, baudRate );
1788 if(err == 0)
1789 cout <<"Opening Port Successful!\n";
1790 else
1791 {
1792 cout <<"Opening Port Failed!\n";
1793 return err;
1794 }
1795 #endif
1796 goto FileTx;
1797 }
1798 else
1799 #ifndef WINDOWS
1800 close(fdesc);
1802 if(!err)
1803 cout << "File Transfer Complete!\n";
1804 else
1805 cout << "File Transfer Failed!\n";
1806 #endif
1807 return err;
1808 }
1809 }
1811 int Init()
1812 {
1813 return 0;
1814 }
1816 int ExecCommand( const char * commandName, const char** optionNames, const char** optionValues, const int optionLen )
1817 {
1818 int retVal = 0;
1819 if(!strcmp(commandName,"FlashErase"))
1820 retVal = FlashErase( optionNames, optionValues, optionLen );
1821 else
1822 cout << "Command not supported!\n";
1823 return retVal;
1824 }
1826 int Shutdown()
1827 {
1828 return 0;
1829 }