/*---------------------------------------------------------------------*/
/* --- Web: www.STCAI.com ---------------------------------------------*/
/*---------------------------------------------------------------------*/

/*************  功能说明    **************

本例程基于AI8051U为主控芯片的实验箱进行编写测试。

使用Keil C51编译器,为了达到比较高的效率,一般建议选择"Small"模式。

当编译器出现 "error C249: 'DATA': SEGMENT TOO LARGE" 错误时，则需要手动将部分比较大的数组通过"xdata" 强制分配到 XDATA 区域(例如: char xdata buffer [256];)

测试外挂的32K xdata程序。
测试方式: 
1: 写入0x55, 并读出判断是否全部是0x55.
2: 写入0xaa, 并读出判断是否全部是0xaa.
3: 写入32768字节的汉字字库(类似于随机数据), 并读出比较.

通过串口2发送单个字符x或X, 开始测试, 并返回相关的测试结果.

串口设置115200bps, 8, N, 1. 切换到P4.6 P4.7.

下载时, 选择时钟 22.1184MHz (用户可自行修改频率).

******************************************/

#include "..\comm\AI8051U.h"
#include "stdio.h"
#include "intrins.h"
#include "Uart2.h"


#define     ExternalRAM_enable()        AUXR |=  2      //允许外部XRAM，禁止使用内部扩展RAM
#define     InternalRAM_enable()        AUXR &= ~2      //禁止外部XRAM，允许使用内部扩展RAM


extern unsigned char code hz[];

/*************  本地常量声明    **************/

#define     XDATA_LENTH     32768   //xdata长度
#define     HZK_LENTH       32768   //字库长度

#define     BUS_SPEED_1T()  BUS_SPEED = 0
#define     BUS_SPEED_2T()  BUS_SPEED = 1
#define     BUS_SPEED_4T()  BUS_SPEED = 2
#define     BUS_SPEED_8T()  BUS_SPEED = 3


/*************  本地变量声明    **************/


void    delay_ms(u8 ms);
u8      TestXRAM(void);
void    TxErrorAddress(void);
void    Xdata_Test(void);

void    delay_ms(u8 ms);
void    RX2_Check(void);
void    PrintString2(u8 *puts);
void    UART2_TxByte(u8 dat);


/***************** 主函数 *****************************/
void main(void)
{
    WTST = 0; 
    P_SW2 |= 0x80;  //扩展寄存器(XFR)访问使能
    CKCON = 0;
    RSTFLAG |= 0x01;
//    P0M1 = 0x30;   P0M0 = 0x30;   //设置P0.4、P0.5为漏极开路(实验箱加了上拉电阻到3.3V)
//    P1M1 = 0x30;   P1M0 = 0x30;   //设置P1.4、P1.5为漏极开路(实验箱加了上拉电阻到3.3V)
//    P2M1 = 0x3c;   P2M0 = 0x3c;   //设置P2.2~P2.5为漏极开路(实验箱加了上拉电阻到3.3V)
//    P3M1 = 0x50;   P3M0 = 0x50;   //设置P3.4、P3.6为漏极开路(实验箱加了上拉电阻到3.3V)
//    P4M1 = 0x3c;   P4M0 = 0x3c;   //设置P4.2~P4.5为漏极开路(实验箱加了上拉电阻到3.3V)
//    P5M1 = 0x0c;   P5M0 = 0x0c;   //设置P5.2、P5.3为漏极开路(实验箱加了上拉电阻到3.3V)
//    P6M1 = 0xff;   P6M0 = 0xff;   //设置为漏极开路(实验箱加了上拉电阻到3.3V)
//    P7M1 = 0x00;   P7M0 = 0x00;   //设置为准双向口

    P0M1 = 0x00;   P0M0 = 0x00;   //设置为准双向口
    P1M1 = 0x30;   P1M0 = 0x00;   //设置为准双向口，P1.4,P1.5设置高阻输入
    P2M1 = 0x00;   P2M0 = 0x00;   //设置为准双向口
    P3M1 = 0x00;   P3M0 = 0x00;   //设置为准双向口
    P4M1 = 0x00;   P4M0 = 0x00;   //设置为准双向口
    P5M1 = 0x00;   P5M0 = 0x00;   //设置为准双向口
    P6M1 = 0x00;   P6M0 = 0x00;   //设置为准双向口
    P7M1 = 0x00;   P7M0 = 0x00;   //设置为准双向口
        P0BP = 0x00;    //设置硬件自动控制P0口模式（默认由P0M1/P0M0控制）

    delay_ms(10);
    UART2_config();
    EA = 1;     //全局中断允许
    P41 = 0;    //扩展SRAM使能
    P27 = 0;    //最高地址位置零

    printf("AI8051U xdata test programme!\n"); //UART2发送一个字符串
    printf("send x or X start test.\n");

    BUS_SPEED_2T(); //1T  2T  4T  8T    3V@22MHZ用1T会访问错误
    BUS_SPEED |= 0x40;      //选择 P3.7为RD，P3.6为WR
    ExternalRAM_enable();   //允许外部XDATA
//  InternalRAM_enable();   //允许内部XDATA

    while (1)
    {
        delay_ms(1);
        if(RX2_Cnt > 0)     //超时计数
        {
            if(--RX2_Cnt == 0)  //串口通讯结束
            {
                RX2_Cnt = 0;
								Xdata_Test();   //单字节命令
            }
        }
    }
}

//========================================================================
// 函数: void delay_ms(unsigned char ms)
// 描述: 延时函数。
// 参数: ms,要延时的ms数, 这里只支持1~255ms. 自动适应主时钟.
// 返回: none.
// 版本: VER1.0
// 日期: 2013-4-1
// 备注: 
//========================================================================
void delay_ms(u8 ms)
{
     u16 i;
     do{
          i = MAIN_Fosc / 6000;
          while(--i);
     }while(--ms);
}


/*************  测试xdata函数 *****************/
u8  TestXRAM(void)
{
    u16 ptc;
    u8  xdata *ptx;
    u16 i,j;

    for(ptx=0; ptx<XDATA_LENTH; ptx++)  *ptx = 0x55;    //测试是否有位短路
    for(ptx=0; ptx<XDATA_LENTH; ptx++)  if(*ptx != 0x55)    return 1;   //测试0x55错误

    for(ptx=0; ptx<XDATA_LENTH; ptx++)  *ptx = 0xaa;    //测试是否有位短路
    for(ptx=0; ptx<XDATA_LENTH; ptx++)  if(*ptx != 0xaa)    return 2;   //测试0xaa错误

    i = 0;
    for(ptx=0; ptx<XDATA_LENTH; ptx++)
    {
        *ptx = (u8)(i >> 8);
        ptx++;
        *ptx = (u8)i;
        i++;
    }
    i = 0;
    for(ptx=0; ptx<XDATA_LENTH; ptx++)
    {
        j = *ptx;
        ptx++;
        j = (j << 8) + *ptx;
        if(i != j)  return 3;   //写连续数字错误
        i++;
    }

    ptx = 0;
    for(ptc=0; ptc<HZK_LENTH; ptc++)    {*ptx = hz[ptc];    ptx++;}
    ptx = 0;
    for(ptc=0; ptc<HZK_LENTH; ptc++)
    {
        if(*ptx != hz[ptc]) return 4;   //写字库错误
        ptx++;
    }

    return 0;
}


/*************  发送错误地址函数 *****************/
void TxErrorAddress(void)
{
    u16 i;
    i = 0x00fd;
    PrintString2("error addr = ");
    if(i >= 10000)  UART2_TxByte(i/10000+'0'),  i %= 10000;
    UART2_TxByte(i/1000+'0'),   i %= 1000;
    UART2_TxByte(i/100+'0'),    i %= 100;
    UART2_TxByte(i/10+'0');
    UART2_TxByte(i%10+'0');
    UART2_TxByte(0x0d);
    UART2_TxByte(0x0a);
}

/*************  xdata测试返回信息函数 *****************/
void Xdata_Test(void)
{
    u8  i;
    if((RX2_Buffer[0] == 'x') || (RX2_Buffer[0] == 'X'))
    {
        PrintString2("Testing xdata, please wait......\n");
        i = TestXRAM();
             if(i == 0) PrintString2("test pass!\n");
        else if(i == 1) PrintString2("test xdata write 0x55 fail!\n"), TxErrorAddress();
        else if(i == 2) PrintString2("test xdata write 0xaa roor!\n"), TxErrorAddress();
        else if(i == 3) PrintString2("Test continuous write error!\n"), TxErrorAddress();
        else if(i == 4) PrintString2("Test writing to font library error!\n"), TxErrorAddress();
    }
}



