Flow Control and Print Format
I got tired of banging my head against the wall with the toolchain compiling. So I decided to just work on something else for a while.
This morning, I connected the CTS and RTS to the RS232 port. So, I’ll start to see if I can do hardware flow control. Which I want since I have 1) a slow processor, 2) a limited 8 byte FIFO in the MAX3110E, and 3) a plan to run at the maximum baud rate. I still have to tie the IRQ to the CPU. Then I’ll be done with communication connections.
I also am working on the parts of the C library that are missing while I’m not getting the toolchain to compile. Since the printf formatting has all kinds of stuff in it, I am just going to write my own minimal formatter. It won’t do everything, but it will do everything I need. No floating point or long long.
I also wrote some test code so I know that it works. At least well enough for now–with correct input.
1 // Formatter for printf, sprintf, vprintf, vsprintf, etc.
2 // This is a very light and minimal formatter that includes only
3 // a subset of the standard functionality. This list explains what
4 // this light version is capable of:
5 // %c - print character
6 // %s - print string
7 // %% - print '%'
8 // %d - print signed int
9 // %x - print unsigned int in hex
10 // %p - print 2 byte unsigned pointer in hex
11 // %#[xduls] - print and pad to # characters. If # starts with 0, use
12 // leading zeros on unsigned int/long
13 // %-#[sulds] - as above, but right justify
14 // %l[xd] - 4 byte long instead of 2 byte int
15 // %u[xd] - unsigned
16
17 void print_int(uint32_t data, int base, bool isUnsigned, bool leadingZeroes, int size, int length, bool rightJustify, char** pBuffer, void(*write)(char c, char** pBuffer))
18 {
19 char buf[BUFLEN];
20 static const char* ascii = "0123456789abcdef";
21 int i = BUFLEN - 1;
22 bool negSign = false;
23 uint32_t udata = data;
24 if (!isUnsigned && ((int32_t)data) < 0)
25 {
26 negSign = true;
27 udata = (~data) + 1;
28 }
29 if (size == 2)
30 {
31 udata &= 0xffff;
32 }
33 do
34 {
35 buf[i--] = ascii[udata % base];
36 udata = udata / base;
37 } while (udata != 0);
38
39 if (negSign)
40 {
41 buf[i--] = '-';
42 }
43 while (i >= 0 && length > (BUFLEN - i))
44 {
45 buf[i--] = leadingZeroes ? '0' : ' ';
46 }
47 i++; // move to the valid data
48 for (; i < BUFLEN; i++)
49 {
50 write(buf[i], pBuffer);
51 }
52 }
53
54 int print_format(void(*write)(char c, char** pBuffer), char** pBuffer, const char* format, va_list ap)
55 {
56 char c;
57 char* start = *pBuffer;
58 int16_t len;
59 bool isunsigned;
60 int16_t base;
61 bool leadingZero;
62 bool neg;
63 int16_t padding;
64 long data;
65 char* p;
66 int i;
67
68 // while not at end of line
69 while (c = *format++)
70 {
71 if (c != '%')
72 {
73 write(c, pBuffer);
74 }
75 else
76 {
77 bool done = false;
78 len = 2;
79 isunsigned = false;
80 leadingZero = false;
81 neg = false;
82 padding = 0;
83 while (!done)
84 {
85 c = *format++;
86 switch (c)
87 {
88 case '%':
89 write(c, pBuffer);
90 done = true;
91 break;
92 case 's':
93 // get ptr from va_list
94 p = va_arg(ap, char*);
95 if (padding > 0)
96 {
97 int slen = strlen(p);
98 int spaces = padding - slen;
99 if (spaces > 0)
100 {
101 // padded string
102 if (neg)
103 {
104 for (i = 0; i < spaces; i++)
105 {
106 write(' ', pBuffer);
107 }
108 }
109
110 while (c = *p)
111 {
112 write(c, pBuffer);
113 }
114
115 if (!neg)
116 {
117 for (i = 0; i < spaces; i++)
118 {
119 write(' ', pBuffer);
120 }
121 }
122 }
123 else
124 {
125 // string longer than padding
126 while (c = *p)
127 {
128 write(c, pBuffer);
129 }
130 }
131 }
132 else
133 {
134 while (c = *p)
135 {
136 write(c, pBuffer);
137 }
138 }
139 done = true;
140 break;
141 case 'c':
142 c = va_arg(ap, int); // char is promoted to int
143 write(c, pBuffer);
144 done = true;
145 break;
146 case 'h':
147 len = 2;
148 break;
149 case 'u':
150 isunsigned = true;
151 break;
152 case 'l':
153 len = 4;
154 break;
155 case '-':
156 neg = true;
157 break;
158 case '0':
159 if (!padding)
160 {
161 // if no padding yet, then this means leading zeroes are shown
162 leadingZero = true;
163 }
164 // fall through
165 case '1':
166 case '2':
167 case '3':
168 case '4':
169 case '5':
170 case '6':
171 case '7':
172 case '8':
173 case '9':
174 padding = padding * 10 + c - '0';
175 break;
176 case 'p':
177 isunsigned = true;
178 len = 2;
179 case 'd':
180 case 'x':
181 base = c == 'd' ? 10 : 16; // 16 on x or p
182 if (len == 4)
183 {
184 data = va_arg(ap, long);
185 }
186 else
187 {
188 data = va_arg(ap, int);
189 }
190 print_int(data, base, isunsigned, leadingZero, len, padding, neg, pBuffer, write);
191 done = true;
192 break;
193 }
194 }
195 }
196 }
197 **pBuffer = '\0';
198 return *pBuffer - start;
199 }