Initial commit
This commit is contained in:
368
target/linux/at91/image/dfboot/src/com.c
Normal file
368
target/linux/at91/image/dfboot/src/com.c
Normal file
@@ -0,0 +1,368 @@
|
||||
/*----------------------------------------------------------------------------
|
||||
* ATMEL Microcontroller Software Support - ROUSSET -
|
||||
*----------------------------------------------------------------------------
|
||||
* The software is delivered "AS IS" without warranty or condition of any
|
||||
* kind, either express, implied or statutory. This includes without
|
||||
* limitation any warranty or condition with respect to merchantability or
|
||||
* fitness for any particular purpose, or against the infringements of
|
||||
* intellectual property rights of others.
|
||||
*----------------------------------------------------------------------------
|
||||
* File Name : com.c
|
||||
* Object :
|
||||
* Creation : HIi 03/27/2003
|
||||
*
|
||||
*----------------------------------------------------------------------------
|
||||
*/
|
||||
#include "AT91RM9200.h"
|
||||
#include "lib_AT91RM9200.h"
|
||||
#include "config.h"
|
||||
#include "com.h"
|
||||
#include "stdio.h"
|
||||
|
||||
static char erase_seq[] = "\b \b"; /* erase sequence */
|
||||
|
||||
#define MAX_UARTS 1
|
||||
|
||||
//unsigned int usa[2] = {(unsigned int)AT91C_BASE_DBGU, (unsigned int)AT91C_ALTERNATE_USART};
|
||||
unsigned int usa[1] = {(unsigned int)AT91C_BASE_DBGU};
|
||||
unsigned int us;
|
||||
int port_detected;
|
||||
|
||||
void at91_init_uarts(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
port_detected = 0;
|
||||
AT91F_DBGU_CfgPIO();
|
||||
AT91F_US0_CfgPIO();
|
||||
AT91F_US0_CfgPMC();
|
||||
|
||||
for(i=0; i<MAX_UARTS; i++) {
|
||||
us = usa[i];
|
||||
AT91F_US_ResetRx((AT91PS_USART)us);
|
||||
AT91F_US_ResetTx((AT91PS_USART)us);
|
||||
|
||||
// Configure DBGU
|
||||
AT91F_US_Configure(
|
||||
(AT91PS_USART)us, // DBGU base address
|
||||
AT91C_MASTER_CLOCK, // 60 MHz
|
||||
AT91C_US_ASYNC_MODE, // mode Register to be programmed
|
||||
115200, // baudrate to be programmed
|
||||
0 // timeguard to be programmed
|
||||
);
|
||||
|
||||
// Enable Transmitter
|
||||
AT91F_US_EnableTx((AT91PS_USART)us);
|
||||
// Enable Receiver
|
||||
AT91F_US_EnableRx((AT91PS_USART)us);
|
||||
}
|
||||
us = usa[0];
|
||||
}
|
||||
|
||||
int at91_serial_putc(int ch)
|
||||
{
|
||||
if (ch == '\n')
|
||||
at91_serial_putc('\r');
|
||||
while (!AT91F_US_TxReady((AT91PS_USART)us));
|
||||
AT91F_US_PutChar((AT91PS_USART)us, (char)ch);
|
||||
return ch;
|
||||
}
|
||||
|
||||
/* This getc is modified to be able work on more than one port. On certain
|
||||
* boards (i.e. Figment Designs VersaLink), the debug port is not available
|
||||
* once the unit is in it's enclosure, so, if one needs to get into dfboot
|
||||
* for any reason it is impossible. With this getc, it scans between the debug
|
||||
* port and another port and once it receives a character, it sets that port
|
||||
* as the debug port. */
|
||||
int at91_serial_getc()
|
||||
{
|
||||
while(1) {
|
||||
#if 0
|
||||
if (!port_detected) {
|
||||
if (us == usa[0]) {
|
||||
us = usa[1];
|
||||
}
|
||||
else {
|
||||
us = usa[0];
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if(AT91F_US_RxReady((AT91PS_USART)us)) {
|
||||
#if 0
|
||||
port_detected = 1;
|
||||
#endif
|
||||
return((int)AT91F_US_GetChar((AT91PS_USART)us));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
* Function Name : AT91F_ReadLine()
|
||||
* Object :
|
||||
* Input Parameters :
|
||||
* Return value :
|
||||
*-----------------------------------------------------------------------------
|
||||
*/
|
||||
int AT91F_ReadLine (const char *const prompt, char *console_buffer)
|
||||
{
|
||||
char *p = console_buffer;
|
||||
int n = 0; /* buffer index */
|
||||
int plen = strlen (prompt); /* prompt length */
|
||||
int col; /* output column cnt */
|
||||
char c;
|
||||
|
||||
/* print prompt */
|
||||
if (prompt)
|
||||
printf(prompt);
|
||||
col = plen;
|
||||
|
||||
for (;;) {
|
||||
c = getc();
|
||||
|
||||
switch (c) {
|
||||
case '\r': /* Enter */
|
||||
case '\n':
|
||||
*p = '\0';
|
||||
puts ("\n");
|
||||
return (p - console_buffer);
|
||||
|
||||
case 0x03: /* ^C - break */
|
||||
console_buffer[0] = '\0'; /* discard input */
|
||||
return (-1);
|
||||
|
||||
case 0x08: /* ^H - backspace */
|
||||
case 0x7F: /* DEL - backspace */
|
||||
if (n) {
|
||||
--p;
|
||||
printf(erase_seq);
|
||||
col--;
|
||||
n--;
|
||||
}
|
||||
continue;
|
||||
|
||||
default:
|
||||
/*
|
||||
* Must be a normal character then
|
||||
*/
|
||||
if (n < (AT91C_CB_SIZE -2))
|
||||
{
|
||||
++col; /* echo input */
|
||||
putc(c);
|
||||
*p++ = c;
|
||||
++n;
|
||||
}
|
||||
else
|
||||
{ /* Buffer full */
|
||||
putc('\a');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
* Function Name : AT91F_WaitKeyPressed()
|
||||
* Object :
|
||||
* Input Parameters :
|
||||
* Return value :
|
||||
*-----------------------------------------------------------------------------
|
||||
*/
|
||||
void AT91F_WaitKeyPressed(void)
|
||||
{
|
||||
int c;
|
||||
puts("KEY");
|
||||
c = getc();
|
||||
putc('\n');
|
||||
}
|
||||
|
||||
int puts(const char *str)
|
||||
{
|
||||
while(*str != 0) {
|
||||
at91_serial_putc(*str);
|
||||
str++;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int putc(int c)
|
||||
{
|
||||
return at91_serial_putc(c);
|
||||
}
|
||||
|
||||
int putchar(c)
|
||||
{
|
||||
return putc(c);
|
||||
}
|
||||
|
||||
int getc()
|
||||
{
|
||||
return at91_serial_getc();
|
||||
}
|
||||
|
||||
int strlen(const char *str)
|
||||
{
|
||||
int len = 0;
|
||||
|
||||
if(str == (char *)0)
|
||||
return 0;
|
||||
|
||||
while(*str++ != 0)
|
||||
len++;
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
#define ZEROPAD 1 /* pad with zero */
|
||||
#define SIGN 2 /* unsigned/signed long */
|
||||
#define LEFT 4 /* left justified */
|
||||
#define LARGE 8 /* use 'ABCDEF' instead of 'abcdef' */
|
||||
|
||||
#define do_div(n,base) ({ \
|
||||
int __res; \
|
||||
__res = ((unsigned) n) % (unsigned) base; \
|
||||
n = ((unsigned) n) / (unsigned) base; \
|
||||
__res; \
|
||||
})
|
||||
|
||||
static int number(int num, int base, int size,
|
||||
int precision, int type)
|
||||
{
|
||||
char c, sign, tmp[66];
|
||||
const char *digits="0123456789ABCDEF";
|
||||
int i;
|
||||
|
||||
if (type & LEFT)
|
||||
type &= ~ZEROPAD;
|
||||
if (base < 2 || base > 16)
|
||||
return 0;
|
||||
c = (type & ZEROPAD) ? '0' : ' ';
|
||||
sign = 0;
|
||||
|
||||
if(type & SIGN && num < 0)
|
||||
{
|
||||
sign = '-';
|
||||
num = -num;
|
||||
size--;
|
||||
}
|
||||
|
||||
i = 0;
|
||||
if(num == 0)
|
||||
tmp[i++] = digits[0];
|
||||
else while(num != 0)
|
||||
tmp[i++] = digits[do_div(num, base)];
|
||||
|
||||
if(i > precision)
|
||||
precision = i;
|
||||
size -= precision;
|
||||
|
||||
if(!(type&(ZEROPAD+LEFT)))
|
||||
while(size-->0)
|
||||
putc(' ');
|
||||
|
||||
if(sign)
|
||||
putc(sign);
|
||||
|
||||
if (!(type & LEFT))
|
||||
while (size-- > 0)
|
||||
putc(c);
|
||||
|
||||
while (i < precision--)
|
||||
putc('0');
|
||||
|
||||
while (i-- > 0)
|
||||
putc(tmp[i]);
|
||||
|
||||
while (size-- > 0)
|
||||
putc(' ');;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int hvfprintf(const char *fmt, va_list va)
|
||||
{
|
||||
char *s;
|
||||
|
||||
do {
|
||||
if(*fmt == '%') {
|
||||
bool done = false;
|
||||
|
||||
int type = 0;
|
||||
int precision = 0;
|
||||
|
||||
do {
|
||||
fmt++;
|
||||
switch(*fmt) {
|
||||
case '0' :
|
||||
if(!precision)
|
||||
type |= ZEROPAD;
|
||||
case '1' :
|
||||
case '2' :
|
||||
case '3' :
|
||||
case '4' :
|
||||
case '5' :
|
||||
case '6' :
|
||||
case '7' :
|
||||
case '8' :
|
||||
case '9' :
|
||||
precision = precision * 10 + (*fmt - '0');
|
||||
break;
|
||||
case '.' :
|
||||
break;
|
||||
case 's' :
|
||||
s = va_arg(va, char *);
|
||||
if(!s)
|
||||
puts("<NULL>");
|
||||
else
|
||||
puts(s);
|
||||
done = true;
|
||||
break;
|
||||
case 'c' :
|
||||
putc(va_arg(va, int));
|
||||
done = true;
|
||||
break;
|
||||
case 'd' :
|
||||
number(va_arg(va, int), 10, 0, precision, type);
|
||||
done = true;
|
||||
break;
|
||||
case 'x' :
|
||||
case 'X' :
|
||||
number(va_arg(va, int), 16, 0, precision, type);
|
||||
done = true;
|
||||
break;
|
||||
case '%' :
|
||||
putc(*fmt);
|
||||
done = true;
|
||||
default:
|
||||
putc('%');
|
||||
putc(*fmt);
|
||||
done = true;
|
||||
break;
|
||||
}
|
||||
} while(!done);
|
||||
} else if(*fmt == '\\') {
|
||||
fmt++;
|
||||
if(*fmt == 'r') {
|
||||
putc('\r');
|
||||
} else if(*fmt == 'n') {
|
||||
putc('\n');
|
||||
}
|
||||
} else {
|
||||
putc(*fmt);
|
||||
}
|
||||
fmt++;
|
||||
} while(*fmt != 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int printf(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
int i;
|
||||
|
||||
va_start(ap, fmt);
|
||||
i = hvfprintf(fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
return i;
|
||||
}
|
||||
Reference in New Issue
Block a user