//-------------------------------------------------------------------------*
// 工 程 名: Light                                                         *
// 硬件连接: 小灯接在Light_Run_PORT口的Light_Run脚,可到Light.h文件中修改   *
//           宏定义来改变端口和引脚                                        *
// 程序描述: 用I/O口控制小灯闪烁                                           *
// 目    的: 第一个Freescale AW系列MCU C语言程序框架                       *
// 说    明: 提供Freescale MCU的编程框架，供教学入门使用                   *
//---------------苏州大学飞思卡尔嵌入式系统实验室2010年--------------------*

#include "Includes.h"


//在此添加全局变量定义
uint8 time[3];                     //存放"时分秒"的值
uint8 SerialBuff[36];              //存放接收数据的数组
uint8 LCDLen;                      //存放接收LCD数据的长度
uint8 LEDBuff[4];                  //存放接收LED数据的数组
uint8 ShowBuff[33];                //存放LCD数据的数组
uint8 LightBuff;                   //存放小灯数据的数组
uint8 pwmDutyPC;		               //接受客户端发送的占空比
uint8 chanelNum;	                 //接受客户端通道号
uint8 FlashLen;                    //Flash数据的长度
uint8 FlashBuff[64];               //Flash数据的数组
uint8 gSCI_ISR_buffer[64];         //存放接收到的帧的数组
uint8 gSCI_ISR_flag;               //组帧完成标志位
uint8 datalen;                     //帧的有效数据长度
uint8 commandtype;                 //标志帧的命令类型

//主函数
void main()
{
    //仅在本函数中用
    uint8 i;                      //临时变量
    uint8 data_AD;                //接收AD值
    uint8 run_COP = 0;            //标志是否执行看门狗程序
    uint8 feed_COP = 0;           //标志是否喂狗
    uint16 len;                   //指定长度的临时变量
    uint16 cmd_flash;             //FLASH判定功能
    uint32 mRuncount = 0;         //运行计数器
    uint32 mRuncount2 = 0;        //运行计数器2
    
    //定义初始显示缓存并赋初值
    const uint8 DisPalyInit[]
                = "Wait Receiving.. Soochow 2011.10";                     
    LCDLen=0;                     //LCD液晶屏显示数据长度
    chanelNum = 30;	              //为30，说明没有收到AD转换的客户端信息
    pwmDutyPC = 101;              //为101，则不执行PWM
    commandtype = 0;              //功能标志为0，不执行任何功能模块


    //关总中断
DisableInterrupt();               //禁止总中断

    //1. 芯片初始化
    MCUInit();
    
    //2. 模块初始化
    SCIInit(1,SYSTEM_CLOCK,9600); //(1) 串口初始化
    Light_Init(Light_Run_PORT,Light_Run,Light_OFF); //(2) 灯和蜂鸣器的引脚初始化
    LEDinit();                    //(3) LED初始化 
    LCDshow((uint8 *)DisPalyInit);//(4) LCD初始化
    KBInit();                     //(5) 按键初始化
    TPMinit(2);                   //(6) 定时器2初始化
    ADCInit();	                  //(7)AD初始化 
    PWM(1,0,0x800,0);            	//(8)定时器2通道0初始输出占空比为0周期为1s的PWM波
    FlashInit(SYSTEM_CLOCK*1000); //(9)Flash初始化
   
    //3. 内存初始化
    //(1) "时分秒"缓存初始化(00:00:00)
    FeedDog();
    time[0] = 0;
    time[1] = 0;
    time[2] = 0;
    //(2) 小灯状态初始化3,表示没有命令发送过来
    LightBuff = 3;
    //(3) 数码管状态初始化
    LEDBuff[0]='8';
    LEDBuff[1]='8';
    LEDBuff[2]='8';
    LEDBuff[3]='8';
    
    //4. 开放各模块中断
    EnableSCIReInt();             //开放SCI接收中断 
    EnableTimer(2);               //开放定时器1溢出中断
    EnableKBint();                //开放键盘中断

EnableInterrupt();                //开放总中断
    //主程序向PC发送数据
    FeedDog();
    if(feed_COP == 0) 
    {
      SCISend1(1,COPfd_commandtype); 
      SCISendString(1,"START");
    }   
    
//主循环
    while (1)
    {
        if(gSCI_ISR_flag==1) 
        {
            datalen = gSCI_ISR_buffer[1];    //有效数据的长度
            commandtype = gSCI_ISR_buffer[2];//类型标识
            switch (commandtype)
            {
               case SCI_commandtype:         //串口测试功能
                    for(i=0;i<datalen;i++) 
                    {   FeedDog();
                        ShowBuff[i]=gSCI_ISR_buffer[i+3];
                    } 
                    SCISend1(1,SCI_commandtype);
                    SCISendN(1,datalen,ShowBuff);
                    break;
                    
                case Light_commandtype:     //light模块
                    FeedDog();
      	            LightBuff=gSCI_ISR_buffer[3];
       	            Light_Change(Light_Run_PORT,Light_Run);
       	            SCISend1(1,Light_commandtype);//发送串口的标志
       	            SCISend1(1,LightBuff);
       	            break;
       	            
       	       case LED_commandtype:       //LED标志
                    FeedDog();
                    //接收4个字节的数据
                    LEDBuff[0]=gSCI_ISR_buffer[3];
                    LEDBuff[1]=gSCI_ISR_buffer[4];
                    LEDBuff[2]=gSCI_ISR_buffer[5];
                    LEDBuff[3]=gSCI_ISR_buffer[6];
                    SCISend1(1,LED_commandtype);
                    SCISendN(1,4, LEDBuff);
                    for(i=0;i<4;i++) 
                    {
                        LEDBuff[i]+='0';
                    }
                    break;
       	            
                case LCD_commandtype:       //LCD标志 
                    for(i=0;i<datalen;i++) 
                    {
                        FeedDog();
                        ShowBuff[i]=gSCI_ISR_buffer[i+3];//将接收的数据转入LCD缓冲
                    } 
                    for(i=datalen;i<32;i++) 
                    {
                        ShowBuff[i]=' ';
                    }
                    LCDshow(ShowBuff);
                    SCISend1(1,LCD_commandtype);
                    SCISendN(1,32,ShowBuff);
                    break;
                    
                case Timer_commandtype:     //时钟标志
                    FeedDog();
                    //接收3个字节的数据
                    time[0]=gSCI_ISR_buffer[3];
                    time[1]=gSCI_ISR_buffer[4];
                    time[2]=gSCI_ISR_buffer[5];
                    break;
                    
                case PWM_commandtype:       //pwm处理模块
                    pwmDutyPC = gSCI_ISR_buffer[3];
                    if(pwmDutyPC<101)
    	              {
    	                  FeedDog();
    	                  PWM(1,0,0x800,pwmDutyPC);
      		              pwmDutyPC = 101;
    	              }
    	              break;
    	              
                case AD_commandtype:          //AD模块
                    FeedDog();
                    chanelNum = gSCI_ISR_buffer[3];
                    if(chanelNum<30)
    	              {
    	                  data_AD = (uint8)ADCAve(chanelNum, 50);
    	                  SCISend1(1,AD_commandtype); 
      	                SCISend1(1,data_AD);
      	                chanelNum = 30;
    	             }
    	             break;
    	             
                case Flash_commandtype:       //Flash模块 
                    for(i=0;i<datalen;i++) 
                    {   
                        FeedDog();
                        FlashBuff[i]=gSCI_ISR_buffer[i+3];
                    }
                    SCISend1(1,Flash_commandtype);  
                    len = 0;
                    len=datalen;
                    datalen=0;
                    cmd_flash=FlashBuff[0];
                    FeedDog(); 
                    switch (cmd_flash)
                    {
                        case '?'://命令帮助
                            Display_Flash_Help(); 
                            break;	
                        case 'E'://擦除
                            Display_Flash_E(len,FlashBuff);   
                            break;
                        case 'R'://读取 
                            Display_Flash_R(len,FlashBuff);
                            break;  
                        case 'W'://写入              	
    			                  Display_Flash_W(len,FlashBuff);
                            break;  
                        case 'B'://设置后门密钥
    			                  Display_Flash_B(len,FlashBuff);
                            break;           
                        case 'M'://后门密钥验证
    				                Display_Flash_M(len,FlashBuff);
                            break;
                        case 'P'://块保护
    				                Display_Flash_P(len,FlashBuff);
    			                  break; 
                        case 'D':  //删除密钥
                            Display_Flash_D();
                            break;
                        case 'U':  //解除加密
                            Display_Flash_U();
                            break; 
                        case 'S': //查看块保护地址和保密字节
                            Display_Flash_S();
                            break;
                        case 'K': //查看密钥
                            Display_Flash_K();
                            break;    
                        default:
                            break;
                    }
                    
                case COPfd_commandtype:          //开启看门狗且喂狗
                    feed_COP=1;
                    run_COP=1;
                    break;
                    
                case COPno_commandtype:          //开启看门狗且不喂狗 
                    feed_COP=2;
                    run_COP=1;
                    break;
                    
                default:
                    FeedDog();
                    break;  
            }
            gSCI_ISR_flag=0;                     //互斥访问帧 
        }
          
        if(run_COP==1)//看门狗程序段，run_COP=0不执行看门狗程序，为1执行看门狗程序                                    
        {
            SCISend1(1,COPfd_commandtype);
      	    if(feed_COP==1)                      //喂狗的情况
            { 
                 mRuncount++; 
    	           FeedDog();
    	           if(mRuncount>=1500) 
    	           {
    	                mRuncount=0; 
     	   	            FeedDog();   //字符超过10个看门狗溢出
    	   	            SCISendString(1,"<********OK********>");
      	         }  
            }
            else if(feed_COP==2)                 //不喂狗的情况
            {
    	           mRuncount++;
    	           if(mRuncount>=1500) 
    	           {
    	                mRuncount=0;    
    	   	            SCISendString1(1,"<********OK********>");
    	           }
            }
            else break;
        }//end if
        LEDshow(LEDBuff);                        //LED液晶显示
    }//end while
} //end main


