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.
// Formatter for printf, sprintf, vprintf, vsprintf, etc.
// This is a very light and minimal formatter that includes only
// a subset of the standard functionality. This list explains what
// this light version is capable of:
// %c - print character
// %s - print string
// %% - print '%'
// %d - print signed int
// %x - print unsigned int in hex
// %p - print 2 byte unsigned pointer in hex
// %#[xduls] - print and pad to # characters. If # starts with 0, use
// leading zeros on unsigned int/long
// %-#[sulds] - as above, but right justify
// %l[xd] - 4 byte long instead of 2 byte int
// %u[xd] - unsigned
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))
{
char buf[BUFLEN];
static const char* ascii = "0123456789abcdef";
int i = BUFLEN - 1;
bool negSign = false;
uint32_t udata = data;
if (!isUnsigned && ((int32_t)data) < 0)
{
negSign = true;
udata = (~data) + 1;
}
if (size == 2)
{
udata &= 0xffff;
}
do
{
buf[i--] = ascii[udata % base];
udata = udata / base;
} while (udata != 0);
if (negSign)
{
buf[i--] = '-';
}
while (i >= 0 && length > (BUFLEN - i))
{
buf[i--] = leadingZeroes ? '0' : ' ';
}
i++; // move to the valid data
for (; i < BUFLEN; i++)
{
write(buf[i], pBuffer);
}
}
int print_format(void(*write)(char c, char** pBuffer), char** pBuffer, const char* format, va_list ap)
{
char c;
char* start = *pBuffer;
int16_t len;
bool isunsigned;
int16_t base;
bool leadingZero;
bool neg;
int16_t padding;
long data;
char* p;
int i;
// while not at end of line
while (c = *format++)
{
if (c != '%')
{
write(c, pBuffer);
}
else
{
bool done = false;
len = 2;
isunsigned = false;
leadingZero = false;
neg = false;
padding = 0;
while (!done)
{
c = *format++;
switch (c)
{
case '%':
write(c, pBuffer);
done = true;
break;
case 's':
// get ptr from va_list
p = va_arg(ap, char*);
if (padding > 0)
{
int slen = strlen(p);
int spaces = padding - slen;
if (spaces > 0)
{
// padded string
if (neg)
{
for (i = 0; i < spaces; i++)
{
write(' ', pBuffer);
}
}
while (c = *p)
{
write(c, pBuffer);
}
if (!neg)
{
for (i = 0; i < spaces; i++)
{
write(' ', pBuffer);
}
}
}
else
{
// string longer than padding
while (c = *p)
{
write(c, pBuffer);
}
}
}
else
{
while (c = *p)
{
write(c, pBuffer);
}
}
done = true;
break;
case 'c':
c = va_arg(ap, int); // char is promoted to int
write(c, pBuffer);
done = true;
break;
case 'h':
len = 2;
break;
case 'u':
isunsigned = true;
break;
case 'l':
len = 4;
break;
case '-':
neg = true;
break;
case '0':
if (!padding)
{
// if no padding yet, then this means leading zeroes are shown
leadingZero = true;
}
// fall through
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
padding = padding * 10 + c - '0';
break;
case 'p':
isunsigned = true;
len = 2;
case 'd':
case 'x':
base = c == 'd' ? 10 : 16; // 16 on x or p
if (len == 4)
{
data = va_arg(ap, long);
}
else
{
data = va_arg(ap, int);
}
print_int(data, base, isunsigned, leadingZero, len, padding, neg, pBuffer, write);
done = true;
break;
}
}
}
}
**pBuffer = '\0';
return *pBuffer - start;
}
No comments:
Post a Comment