#include "common.h"
#include "regs.h"
#include <stdarg.h>
#define CMD_HISTORY_MAX 20
/*va_list
*va_start
*va_end
*va_arg
*/
/*检查上次数据是否发完,参考S3C6410手册P1096*/
#define TR_BUSY while(!(UTRSTAT0 & 2))
/*检查是否收到数据,参考S3C6410手册P1096*/
#define RC_BUSY while(!(UTRSTAT0 & 1))
char cmd_history[CMD_HISTORY_MAX][1024];
int cmd_history_last;
int cmd_history_lastm;
int cmd_history_first;
void uart_init(void)
{
/*设置GPA0-1为UART_com0功能,参考S3C6410手册P312*/
GPACON &= ~(0xff);
GPACON |= 0x22;
/*设置8N1,参考S3C6410手册P1091*/
ULCON0 = 3;
/*设置采用轮询模式,参考S3C6410手册P1092*/
UCON0 |= (1 << 2) | (1 << 0);
/*把FIFO关掉*/
UFCON0 = 0;
UMCON0 = 0;
/*配置波特率为115200,参考S3C6410手册P1101*/
UBRDIV0 = 34;//34.8<--115200
UDIVSLOT0 = 0xdfdd;//13<--0.8
cmd_history_last = 0;
cmd_history_lastm = 0;
cmd_history_first = 0;
}
void uputchar(char c)
{
TR_BUSY;
/*把要发送的数据写到发送寄存器,参考S3C6410手册P1100*/
UTXH0 = c;
}
char ugetchar(void)
{
RC_BUSY;
/*硬件会把收到的数据自动放到URXH0里,参考S3C6410手册P1100*/
return URXH0;
}
void _uputs(char *buf)
{
while(*buf != '\0'){
uputchar(*buf);
if(*buf == '\n'){
uputchar('\r');
}
buf++;
}
}
void uputs(char *buf)
{
_uputs(buf);
uputchar('\n');
uputchar('\r');
}
int uprintf(const char *fmt, ...);
extern int status;
char *ugets(char *buf)
{
char *save = buf;
char c;
int p=0,m=0,key_dir = 0;
char d[10];
int n, i,temp;
n=0;
int buf_cmd_p = cmd_history_lastm;
int buf_cmd_pd = cmd_history_lastm;
char buf_temp[1024];
int buf_status = 0;
int buf_first_flag = 0;
*buf = '\0';
while((c = ugetchar()) != '\r'){
if( (c<='9' && c>='0') || (c<='z' && c>='a') || (c<='Z' && c>='A') || c==' ' || c=='"' || c==',' || c=='.' || c=='#' ){
if( key_dir==2 && (c=='A' || c=='B' || c=='C' || c=='D')){
if(c==68){
if(p!=0){
p--;
uputchar(27);uputchar(91);uputchar(c);
continue;
}
}else if(c == 67){
if(p!=m){
p++;
uputchar(27);uputchar(91);uputchar(c);
continue;
}
}else if(c == 65){
// uprintf("buf: %s\n",buf);
// uprintf("cmd_history_first: %d, cmd_history_last: %d\n",cmd_history_first, cmd_history_last);
// uprintf("buf_cmd_p: %d\n",buf_cmd_p);
if(cmd_history_last == cmd_history_first)
continue;
if( buf_first_flag == 1){
continue;
}
if(buf_status == 0){
buf_status = 1;
strcpy(buf_temp, buf);
}
strcpy(buf, cmd_history[buf_cmd_p]);
buf_cmd_pd = buf_cmd_p--;
if(buf_cmd_p == -1)
buf_cmd_p = CMD_HISTORY_MAX-1;
if(buf_cmd_pd == cmd_history_first)
buf_first_flag = 1;
for(i=0; i<p;i++)
uputchar(8);
for(i=0; i<m; i++)
uputchar(' ');
for(i=0; i<m; i++)
uputchar(8);
p= strlen(buf);
m= strlen(buf);
_uputs(buf);
}else if( c == 66){
if(buf_status == 0)
continue;
if(buf_first_flag == 1){
buf_first_flag = 0;
}
buf_cmd_p = buf_cmd_pd++;
if(buf_cmd_pd == CMD_HISTORY_MAX)
buf_cmd_pd = 0;;
if(buf_cmd_p == cmd_history_lastm){
strcpy(buf,buf_temp);
buf_first_flag = 0;
buf_status = 0;
}else{
strcpy(buf,cmd_history[buf_cmd_pd]);
}
for(i=0; i<p;i++)
uputchar(8);
for(i=0; i<m; i++)
uputchar(' ');
for(i=0; i<m; i++)
uputchar(8);
_uputs(buf);
p= strlen(buf);
m= strlen(buf);
}
}else{
for(i=m; i>=p; i--){
buf[i+1] = buf[i];
}
buf[p] = c;
buf[++m] = '\0';
_uputs(buf+p++);
for(i=m; i>p; i--)
uputchar(8);
}
}else if(c == 27){
key_dir=1;
}else if(c == 91){
if(key_dir == 1)
key_dir = 2;
}else if(c == '\b'){
if(p!=0){
for(i=p; i<m+1; i++){
buf[i-1] = buf[i];
}
p--;
m--;
uputchar(8);
_uputs(buf+p);
uputchar(' ');
uputchar(8);
for(i=p; i<m;i++){
uputchar(8);
}
key_dir = 0;
}
}else if(c == 3){
break;
}else{
key_dir = 0;
/*
* 显示按键的ASCII
if(c<10)
uputchar(c+'0');
else{
for(i=0;i<10;++i){
d[i] = c%10;
c = c/10;
if(c<10){
uputchar(c+'0');
break;
}
}
for(;i>=0;--i)
uputchar(d[i]+'0');
}
uputchar(' ');
*/
}
}
buf[m] = '\0';
if(c==3)
*buf = 0;
if(*buf != '\0'){
if( strcmp(buf, cmd_history[cmd_history_lastm]) ){
strcpy(cmd_history[cmd_history_last], buf);
cmd_history_lastm = cmd_history_last++;
if(cmd_history_last == CMD_HISTORY_MAX)
cmd_history_last = 0;
if(cmd_history_last == cmd_history_first){
cmd_history_first++;
if(cmd_history_first == CMD_HISTORY_MAX)
cmd_history_first = 0;
}
}
}
uputchar('\r');
uputchar('\n');
return save;
}
void itoa(unsigned int d, char *buf)
{
int i;
if(d < 10){
buf[0] = d + '0';
buf[1] = '\0';
return;
}
itoa(d / 10, buf);
for(i = 0; buf[i] != '\0'; i++){
;
}
buf[i] = (d % 10) + '0';
buf[i + 1] = '\0';
}
void xtoa(unsigned int d, char *buf)
{
int i;
if(d < 16){
if(d < 10){
buf[0] = d + '0';
buf[1] = '\0';
}else{
buf[0] = d - 10 + 'a';
buf[1] = '\0';
}
return;
}
xtoa(d / 16, buf);
for(i = 0; buf[i] != '\0'; i++){
;
}
if((d % 16) < 10){
buf[i] = (d % 16) + '0';
buf[i + 1] = '\0';
}else{
buf[i] = (d % 16) - 10 + 'a';
buf[i + 1] = '\0';
}
}
/*%s %c %d %x*/
//uprintf("hello %d %c %x %s\n", 10, 'a', 0x100, "d");
//va_start 建立对应关系
//va_end 取消对应关系
//va_list 对应关系变量类型
//va_arg 根据对应关系取出相应的数据
int uprintf(const char *fmt, ...)
{
va_list ap;
char c;
int d;
char *s;
char buf[64];
va_start(ap, fmt);
while(*fmt != '\0'){
if(*fmt == '%'){
fmt++;
switch(*fmt){
case 'c':
c = va_arg(ap, int);
uputchar(c);
break;
case 'd':
d = va_arg(ap, int);
if(d < 0){
uputchar('-');
d = -d;
}
itoa(d, buf);
_uputs(buf);
break;
case 's':
s = va_arg(ap, char *);
_uputs(s);
break;
case 'x':
d = va_arg(ap, int);
xtoa(d, buf);
_uputs(buf);
break;
case '%':
break;
default:
break;
}
}else{
uputchar(*fmt);
if(*fmt == '\n'){
uputchar('\r');
}
}
fmt++;
}
va_end(ap);
}