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                                 printf("|\n");
64                         }
65                         pass = !pass;
66                 }
67         }
68         printf("|\n");
69 }
72 /* ---- Serial utility functions ---------------------------------------------------*/
74 static int serial_fd = -1;
76 /* Open the serial device and set it up.
77  * Returns 0 on success, negativ value on error.
78  * Actal setup is done according to LPC11xx user's manual.
79  * Only baudrate can be changed using command line option.
80  */
81 int isp_serial_open(int baudrate, char* serial_device)
82 {
83         struct termios tio;
85         if (serial_device == NULL) {
86                 printf("No serial device given on command line\n");
87                 return -2;
88         }
90         /* Open serial port */
91         serial_fd = open(serial_device, O_RDWR | O_NONBLOCK);
92         if (serial_fd < 0) {
93                 perror("Unable to open serial_device");
94                 printf("Tried to open \"%s\".\n", serial_device);
95                 return -1;
96         }
97         /* Setup serial port */
98         memset(&tio, 0, sizeof(tio));
99         tio.c_iflag = IXON | IXOFF;  /* See section 21.4.4 of LPC11xx user's manual (UM10398) */
100         tio.c_cflag = CS8 | CREAD | CLOCAL;  /* 8n1, see termios.h for more information */
101         tio.c_cc[VMIN] = 1;
102         tio.c_cc[VTIME] = 5;
103         cfsetospeed(&tio, baudrate);
104         cfsetispeed(&tio, baudrate);
105         tcsetattr(serial_fd, TCSANOW, &tio);
106         
107         return 0;
110 void isp_serial_close(void)
112         close(serial_fd);
115 /* Simple write() wrapper, with trace if enabled */
116 int isp_serial_write(const char* buf, unsigned int buf_size)
118         int nb = 0;
120         if (trace_on) {
121                 printf("Sending %d octet(s) :\n", buf_size);
122                 isp_dump((unsigned char*)buf, buf_size);
123         }
124         nb = write(serial_fd, buf, buf_size);
125         if (nb <= 0) {
126                 perror("Serial write error");
127                 return -1;
128         }
129         return nb;
132 /* Try to read at least "min_read" characters from the serial line.
133  * Returns -1 on error, 0 on end of file, or read count otherwise.
134  */
135 int isp_serial_read(char* buf, unsigned int buf_size, unsigned int min_read)
137         int nb = 0;
138         unsigned int count = 0;
139         
140         if (min_read > buf_size) {
141                 printf("serial_read: buffer too small for min read value.\n");
142                 return -3;
143         }
145         do {
146                 nb = read(serial_fd, &buf[count], (buf_size - count));
147                 if (nb < 0) {
148                         if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) {
149                                 usleep( 5000 );
150                                 continue;
151                         }
152                         perror("Serial read error");
153                         return -1;
154                 } else if (nb == 0) {
155                         printf("serial_read: end of file !!!!\n");
156                         return 0;
157                 }
158                 if (trace_on == 2) {
159                         isp_dump((unsigned char*)(&buf[count]), nb);
160                 }       
161                 count += nb;
162         } while (count < min_read);
164         if (trace_on) {
165                 printf("Received %d octet(s) :\n", count);
166                 isp_dump((unsigned char*)buf, count);
167         }
168         return count;
172 /* ---- UU_Encoding utility functions ----------------------------------------------*/
174 /* FIXME : This is a place-holder forr uuencode and uudecode functions !!! */
175 int isp_uu_encode(char* dest, char* src, unsigned int orig_size)
177         int new_size = 0;
179         while (orig_size--) {
180                 if (*src) {
181                         *dest++ = *src++;
182                         new_size++;
183                 } else {
184                 }
185         }
186         return new_size;
189 int isp_uu_decode(char* dest, char* src, unsigned int orig_size)
191         int new_size = 0;
192         while (orig_size--) {
193                 if (*src) {
194                         *dest++ = *src++;
195                 } else {
196                 }
197                 new_size++;
198         }
199         return new_size;