95a02299e18f35fb2e1baf09429b6174358f87d3
1 /*!***************************************************************************
3 *! FILE NAME : serial.c
5 *! DESCRIPTION: Serial boot stuff for e100boot.
7 *! ---------------------------------------------------------------------------
12 *! 1996 Ronny Raneup Initial version
13 *! 2002 05 02 Ronny Ranerup Moved it into this file
14 *! ---------------------------------------------------------------------------
15 *! (C) Copyright 1999-2003 Axis Communications AB, LUND, SWEDEN
16 *!***************************************************************************/
18 /************************** Include files ********************************/
25 /************************** Type definitions *****************************/
27 /************************** Global variables *****************************/
30 int set_baudrate
= 9600; /* Baudrate for serial boot (after bootloader). */
32 /************************** Constants and macros *************************/
34 /************************** Function prototypes **************************/
36 int SetControlMode(FILE *fd
, int value
, int onoff
);
37 int SetInputMode(FILE *fd
, int value
, int onoff
);
38 int SetLocalMode(FILE *fd
, int value
, int onoff
);
39 int SetOutputMode(FILE *fd
, int value
, int onoff
);
40 int WaitForRead(int s
, int usecs
);
41 int WaitForWrite(int s
, int usecs
);
42 void setBaudRate(unsigned int b
);
44 /****************************************************************************
46 *# FUNCTION NAME: SerBoot
48 *# DESCRIPTION: The main serial boot routine.
50 *#---------------------------------------------------------------------------
55 *# 2000 01 07 ronny Initial version
57 *#***************************************************************************/
68 while ((p
= create_packet(seq
))) {
71 static char fName
[MAX_STRING_LEN
] = {0,};
73 if (strcmp(fName
, p
->boot_file
->fileName
) != 0) {
74 while (connected
&& got_new_ack
== 0) {
75 WaitForRead(fileno(serialFd
), 1000000); /* Did we get data? */
77 if(fread(&rec_buf
, 1, 1, serialFd
) > 0) {
78 fwrite(&rec_buf
, 1, 1, stderr
);
80 printf("# Got ack.\n");
86 strcpy(fName
, p
->boot_file
->fileName
);
87 printf("# transmitting file '%s'\n", fName
);
91 printf("# transmitting %d bytes at baudrate %d.\n", (int)p
->size
, p
->baud_rate
);
93 // setBaudRate(p->baud_rate);
95 while (tr_len
!= p
->size
) {
97 if (WaitForRead(fileno(serialFd
), 0)) { /* Did we get data? */
98 // static int connected = 0;
102 if((rec_len
= fread(&rec_buf
, 1, 1, serialFd
)) > 0) {
103 if (rec_buf
== '+') {
105 printf("# Got ack.\n");
109 printf("# Got ack.\n");
111 fwrite(&rec_buf
, rec_len
, 1, stderr
);
116 if (tr_len
< p
->size
) { /* send one byte */
117 while (!(WaitForWrite(fileno(serialFd
), 1000000))) { }
118 fwrite(&p
->data
[offset
+tr_len
], 1, 1, serialFd
);
123 seq
++; /* We have transmitted entire packet. */
126 printf("# Transmission done. Just listening now.\n");
129 if (WaitForRead(fileno(serialFd
), 10000000)) { /* Did we get data? */
133 if((rec_len
= fread(&rec_buf
, 1, 1, serialFd
)) > 0) {
134 fwrite(&rec_buf
, rec_len
, 1, stderr
);
140 /****************************************************************************
142 *# FUNCTION NAME: SetupSerial
148 *#---------------------------------------------------------------------------
153 *# 970325 ronny Initial version
155 *#***************************************************************************/
160 int baudRates
[] = {0, 50, 75, 110, 134, 150, 200, 300, 600,
161 1200, 1800, 2400, 4800, 9600, 19200, 38400, 57600, 115200};
165 if ((serialFd
= fopen(device
, "r+")) == NULL
) {
166 perror("Can't open modem");
170 /* Important. Remember this!!!!!!! */
171 /* setvbuf(serialFd, NULL, _IONBF, 0); */
173 setvbuf(serialFd
, NULL
, _IONBF
, 0);
174 setvbuf(stdout
, NULL
, _IONBF
, 0);
176 if (fcntl(fileno(serialFd
), F_SETFL
, O_NONBLOCK
) == -1) {
181 tcflush(fileno(serialFd
), TCIOFLUSH
);
183 if (tcgetattr(fileno(serialFd
), &ti
)) {
190 ti
.c_cc
[VSTART
] = 0x11;
191 ti
.c_cc
[VSTOP
] = 0x13;
193 if (tcsetattr(fileno(serialFd
), TCSANOW
, &ti
)) {
198 //if (db3) printf("outspeed: %d, inspeed: %d\n", baudRates[cfgetospeed(&ti)], baudRates[cfgetispeed(&ti)]);
200 int new_baudrate
= 0;
202 if (set_baudrate
<= 50) {
206 else if (set_baudrate
<= 75) {
210 else if (set_baudrate
<= 110) {
214 else if (set_baudrate
<= 134) {
218 else if (set_baudrate
<= 150) {
222 else if (set_baudrate
<= 200) {
226 else if (set_baudrate
<= 300) {
230 else if (set_baudrate
<= 600) {
234 else if (set_baudrate
<= 1200) {
238 else if (set_baudrate
<= 1800) {
242 else if (set_baudrate
<= 2400) {
246 else if (set_baudrate
<= 4800) {
250 else if (set_baudrate
<= 9600) {
254 else if (set_baudrate
<= 19200) {
256 new_baudrate
= 19200;
258 else if (set_baudrate
<= 38400)
260 #if defined(B57600) /* POSIX only defines <= 38400 */
261 else if (set_baudrate
<= 57600) {
263 new_baudrate
= 57600;
267 else if (set_baudrate
<= 115200) {
269 new_baudrate
= 115200;
273 else if (set_baudrate
<= 230400) {
275 new_baudrate
= 230400;
282 cfsetispeed(&ti
, B9600
);
283 cfsetospeed(&ti
, baudrate
);
284 tcsetattr(fileno(serialFd
), TCSANOW
, &ti
);
286 // printf("* baudrate set to %d\n", new_baudrate);
287 set_baudrate
= new_baudrate
;
289 if (db3
) printf("outspeed: %d, inspeed: %d\n", baudRates
[cfgetospeed(&ti
)], baudRates
[cfgetispeed(&ti
)]);
294 SetInputMode(serialFd
, IXON
, FALSE
);
295 SetInputMode(serialFd
, IXOFF
, FALSE
);
296 SetInputMode(serialFd
, IXANY
, FALSE
);
297 SetInputMode(serialFd
, ICRNL
, FALSE
);
298 SetInputMode(serialFd
, IGNPAR
, TRUE
);
299 SetInputMode(serialFd
, IGNBRK
, TRUE
);
300 SetInputMode(serialFd
, IGNPAR
, TRUE
);
301 SetInputMode(serialFd
, INPCK
, FALSE
);
303 SetOutputMode(serialFd
, OPOST
, FALSE
);
304 SetOutputMode(serialFd
, ONLCR
, FALSE
);
306 SetOutputMode(serialFd
, OXTABS
, FALSE
);
310 SetOutputMode(serialFd
, ENOEOT
, FALSE
);
313 SetLocalMode(serialFd
, ECHO
, FALSE
);
314 SetLocalMode(serialFd
, ISIG
, FALSE
);
316 SetLocalMode(serialFd
, ICANON
, FALSE
);
318 SetControlMode(serialFd
, PARENB
, FALSE
);
319 SetControlMode(serialFd
, CLOCAL
, TRUE
);
320 SetControlMode(serialFd
, CREAD
, TRUE
);
322 /* Disable hardware flow control. */
325 SetControlMode(serialFd
, CRTSCTS
, FALSE
);
326 #if defined(CRTSXOFF)
327 SetControlMode(serialFd
, CRTSXOFF
, FALSE
);
330 #elif defined(CCTS_OFLOW)
332 SetControlMode(serialFd
, CCTS_OFLOW
, FALSE
);
333 SetControlMode(serialFd
, CRTS_IFLOW
, FALSE
);
335 #elif defined(CNEW_RTSCTS)
337 SetControlMode(serialFd
, CNEW_RTSCTS
, FALSE
);
340 printf("Cannot set hardware flow control. Set it manually with a terminal program.\n");
347 setBaudRate(unsigned int b
)
349 int baudRates
[] = {0, 50, 75, 110, 134, 150, 200, 300, 600,
350 1200, 1800, 2400, 4800, 9600, 19200, 38400, 57600, 115200};
353 if (tcgetattr(fileno(serialFd
), &ti
)) {
359 /****************************************************************************
361 *# FUNCTION NAME: SetInputMode
367 *#---------------------------------------------------------------------------
372 *# 970325 ronny Initial version
374 *#***************************************************************************/
377 SetInputMode(FILE *fd
, int value
, int onoff
)
379 struct termios settings
;
382 result
= tcgetattr(fileno(fd
), &settings
);
385 perror("error in tcgetattr");
390 settings
.c_iflag
|= value
;
392 settings
.c_iflag
&= ~value
;
394 result
= tcsetattr(fileno(fd
), TCSANOW
, &settings
);
397 perror("error in tcgetattr");
404 /****************************************************************************
406 *# FUNCTION NAME: SetOutputMode
412 *#---------------------------------------------------------------------------
417 *# 2001 May 16 ronny Initial version
419 *#***************************************************************************/
422 SetOutputMode(FILE *fd
, int value
, int onoff
)
424 struct termios settings
;
427 result
= tcgetattr(fileno(fd
), &settings
);
430 perror("error in tcgetattr");
435 settings
.c_oflag
|= value
;
437 settings
.c_oflag
&= ~value
;
439 result
= tcsetattr(fileno(fd
), TCSANOW
, &settings
);
442 perror("error in tcgetattr");
449 /****************************************************************************
451 *# FUNCTION NAME: SetControlMode
457 *#---------------------------------------------------------------------------
462 *# 970325 ronny Initial version
464 *#***************************************************************************/
467 SetControlMode(FILE *fd
, int value
, int onoff
)
470 struct termios settings
;
473 result
= tcgetattr(fileno(fd
), &settings
);
476 perror("error in tcgetattr");
481 settings
.c_cflag
|= value
;
483 settings
.c_cflag
&= ~value
;
485 result
= tcsetattr(fileno(fd
), TCSANOW
, &settings
);
488 perror("error in tcgetattr");
495 /****************************************************************************
497 *# FUNCTION NAME: SetLocalMode
503 *#---------------------------------------------------------------------------
508 *# 970325 ronny Initial version
510 *#***************************************************************************/
513 SetLocalMode(FILE *fd
, int value
, int onoff
)
516 struct termios settings
;
519 result
= tcgetattr(fileno(fd
), &settings
);
522 perror("error in tcgetattr");
527 settings
.c_lflag
|= value
;
529 settings
.c_lflag
&= ~value
;
531 result
= tcsetattr(fileno(fd
), TCSANOW
, &settings
);
534 perror("error in tcgetattr");
542 /****************************************************************************
544 *# FUNCTION NAME: WaitForRead
546 *# PARAMETERS: Timeout in usecs.
550 *#---------------------------------------------------------------------------
555 *# 961001 ronny Initial version
556 *# 971204 ronny usecs was a only one tenth of what it should be.
558 *#***************************************************************************/
561 WaitForRead(int s
, int usecs
)
567 tm
.tv_sec
= usecs
/1000000;
568 tm
.tv_usec
= usecs
%1000000;
573 if ((ret
= select(FD_SETSIZE
, &mask
, NULL
, NULL
, &tm
)) == -1) {
574 printf("<<< select failed with return: %d.\n", ret
);
578 if (db3
) printf("* select returned OK:%d\n", ret
);
581 if (FD_ISSET(s
, &mask
) == 0) {
582 if (db2
) printf("<<< WaitForRead. No data to read.\n");
586 if (db3
) printf("<<< WaitForRead OK. Returned:%d.\n", ret
);
591 /****************************************************************************
593 *# FUNCTION NAME: WaitForWrite
599 *#---------------------------------------------------------------------------
604 *# 2000-11-20 ronny Initial version
606 *#***************************************************************************/
609 WaitForWrite(int s
, int usecs
)
615 tm
.tv_sec
= usecs
/1000000;
616 tm
.tv_usec
= usecs
%1000000;
621 if ((ret
= select(FD_SETSIZE
, NULL
, &mask
, NULL
, &tm
)) == -1) {
622 printf("<<< select failed with return: %d.\n", ret
);
626 if (db3
) printf("* select returned OK:%d\n", ret
);
629 if (FD_ISSET(s
, &mask
) == 0) {
630 if (db2
) printf("<<< WaitForWrite. No data to read.\n");
634 if (db3
) printf("<<< WaitForWrite OK. Returned:%d.\n", ret
);
This page took 0.08763 seconds and 3 git commands to generate.