Synchro now OK, simple read commands (no arguments) working.
[lpctools] / isp_utils.c
1 /*********************************************************************
2  *
3  *   LPC1114 ISP - Utility functions
4  *
5  *********************************************************************/
8 #include <stdlib.h>
9 #include <stdio.h>
10 #include <stdint.h>
12 #include <unistd.h> /* for open, close */
13 #include <fcntl.h>
14 #include <sys/types.h>
15 #include <sys/stat.h>
17 #include <string.h>
19 #include <termios.h>
20 #include <ctype.h>
21 #include <errno.h>
24 extern int trace_on;
26 /* display data as in hexdump -C :
27    00000000  7f 45 4c 46 02 01 01 00  00 00 00 00 00 00 00 00  |.ELF............|
28  */
29 void isp_dump(const unsigned char* buf, unsigned int buf_size)
30 {
31         unsigned int count = 0;
32         char pass = 0;
33         while ((count < buf_size) || (pass == 0)) {
34                 if (count == buf_size) {
35                         while (count & 0x0F) {
36                                 printf("   ");
37                                 count++;
38                         }
39                         pass = 1;
40                         count -= 0x10;
41                 }
42                 if ((count % 0x10) == 0) {
43                         if (pass == 0) {
44                                 printf(" %08x  ", count);
45                         } else {
46                                 printf(" |");
47                         }
48                 }
49                 if (pass == 0) {
50                         printf("%02x ", buf[count]);
51                 } else {
52                         if (isgraph((int)buf[count])) {
53                                 printf("%c", buf[count]);
54                         } else {
55                                 printf(".");
56                         }
57                 }
58                 count++;
59                 if ((count % 0x10) == 0) {
60                         if (pass == 0) {
61                                 count -= 0x10;
62                         } else {
63                                 if (count == buf_size) {
64                                         break; /* prevent infinite loop */
65                                 }
66                                 printf("|\n");
67                         }
68                         pass = !pass;
69                 }
70         }
71         printf("|\n");
72 }
75 /* ---- Serial utility functions ---------------------------------------------------*/
77 static int serial_fd = -1;
79 /* Open the serial device and set it up.
80  * Returns 0 on success, negativ value on error.
81  * Actal setup is done according to LPC11xx user's manual.
82  * Only baudrate can be changed using command line option.
83  */
84 int isp_serial_open(int baudrate, char* serial_device)
85 {
86         struct termios tio;
88         if (serial_device == NULL) {
89                 printf("No serial device given on command line\n");
90                 return -2;
91         }
93         /* Open serial port */
94         serial_fd = open(serial_device, O_RDWR | O_NONBLOCK);
95         if (serial_fd < 0) {
96                 perror("Unable to open serial_device");
97                 printf("Tried to open \"%s\".\n", serial_device);
98                 return -1;
99         }
100         /* Setup serial port */
101         memset(&tio, 0, sizeof(tio));
102         tio.c_iflag = IXON | IXOFF;  /* See section 21.4.4 of LPC11xx user's manual (UM10398) */
103         tio.c_cflag = CS8 | CREAD | CLOCAL;  /* 8n1, see termios.h for more information */
104         tio.c_cc[VMIN] = 1;
105         tio.c_cc[VTIME] = 5;
106         cfsetospeed(&tio, baudrate);
107         cfsetispeed(&tio, baudrate);
108         tcsetattr(serial_fd, TCSANOW, &tio);
109         
110         return 0;
113 void isp_serial_close(void)
115         close(serial_fd);
118 /* Simple write() wrapper, with trace if enabled */
119 int isp_serial_write(const char* buf, unsigned int buf_size)
121         int nb = 0;
123         if (trace_on) {
124                 printf("Sending %d octet(s) :\n", buf_size);
125                 isp_dump((unsigned char*)buf, buf_size);
126         }
127         nb = write(serial_fd, buf, buf_size);
128         if (nb <= 0) {
129                 perror("Serial write error");
130                 return -1;
131         }
132         return nb;
135 /* Try to read at least "min_read" characters from the serial line.
136  * Returns -1 on error, 0 on end of file, or read count otherwise.
137  */
138 int isp_serial_read(char* buf, unsigned int buf_size, unsigned int min_read)
140         int nb = 0;
141         unsigned int count = 0;
142         
143         if (min_read > buf_size) {
144                 printf("serial_read: buffer too small for min read value.\n");
145                 return -3;
146         }
148         do {
149                 nb = read(serial_fd, &buf[count], (buf_size - count));
150                 if (nb < 0) {
151                         if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) {
152                                 usleep( 5000 );
153                                 continue;
154                         }
155                         perror("Serial read error");
156                         return -1;
157                 } else if (nb == 0) {
158                         printf("serial_read: end of file !!!!\n");
159                         return 0;
160                 }
161                 if (trace_on == 2) {
162                         isp_dump((unsigned char*)(&buf[count]), nb);
163                 }       
164                 count += nb;
165         } while (count < min_read);
167         if (trace_on) {
168                 printf("Received %d octet(s) :\n", count);
169                 isp_dump((unsigned char*)buf, count);
170         }
171         return count;
175 /* ---- UU_Encoding utility functions ----------------------------------------------*/
177 /* FIXME : This is a place-holder forr uuencode and uudecode functions !!! */
178 int isp_uu_encode(char* dest, char* src, unsigned int orig_size)
180         int new_size = 0;
182         while (orig_size--) {
183                 if (*src) {
184                         *dest++ = *src++;
185                         new_size++;
186                 } else {
187                 }
188         }
189         return new_size;
192 int isp_uu_decode(char* dest, char* src, unsigned int orig_size)
194         int new_size = 0;
195         while (orig_size--) {
196                 if (*src) {
197                         *dest++ = *src++;
198                 } else {
199                 }
200                 new_size++;
201         }
202         return new_size;