#include "fur.h"
/*--------------------------------------��������-----------------------------------*/
fur_buf_def fur_cmd_buf[FUR_BUF_MAX];//ָ��档
fur8  fur_status;//����״̬����
fur8  fur_start;//�������ָ�롣
fur8  fur_end;//�����βָ�롣
fur8  fur_count;//����ͳ�ƽ����˶�����ָ�
fur8  fur_temp8;//���ڽ���8λ���ݵ���ʱ������
fur8  fur_id;//���ڽ���ID����ʱ������
fur16 fur_temp16;//���ڽ���16λ���ݵ���ʱ������
/*--------------------------------------������-----------------------------------*/
/*-------------------------------------------------------
FUR������ֵ��������10���Ƶĸ�ʽ���͡�
-------------------------------------------------------*/
#if FUR_UART_SEND_EN
void fur_send_num_10(u16 num){
    u8 a,b,c,d,e;
    a=num/10000;
    b=num%10000/1000;
    c=num%1000/100;
    d=num%100/10;
    e=num%10/1;
    if(a)fur_set_uart(a+'0');
    if(a|b)fur_set_uart(b+'0');
    if(a|b|c)fur_set_uart(c+'0');
    if(a|b|c|d)fur_set_uart(d+'0');
    fur_set_uart(e+'0');
}
#endif
/*-------------------------------------------------------
FUR������ֵ��������16���Ƶĸ�ʽ���͡�
-------------------------------------------------------*/
#if FUR_UART_SEND_EN
void fur_send_num_16(u16 num){
    u8 i;
    u16 temp16;
    temp16=num;
    for(i=0;i<4;i++){
        switch(temp16&0xF000){
            case 0x0000:{fur_set_uart('0');}break;
            case 0x1000:{fur_set_uart('1');}break;
            case 0x2000:{fur_set_uart('2');}break;
            case 0x3000:{fur_set_uart('3');}break;
            case 0x4000:{fur_set_uart('4');}break;
            case 0x5000:{fur_set_uart('5');}break;
            case 0x6000:{fur_set_uart('6');}break;
            case 0x7000:{fur_set_uart('7');}break;
            case 0x8000:{fur_set_uart('8');}break;
            case 0x9000:{fur_set_uart('9');}break;
            case 0xA000:{fur_set_uart('A');}break;
            case 0xB000:{fur_set_uart('B');}break;
            case 0xC000:{fur_set_uart('C');}break;
            case 0xD000:{fur_set_uart('D');}break;
            case 0xE000:{fur_set_uart('E');}break;
            case 0xF000:{fur_set_uart('F');}break;
        }
        temp16<<=4;
    }
}
#endif
/*-------------------------------------------------------
FUR�Ĵ�������������
-------------------------------------------------------*/
fur16 fur_reg_operate(u8 buf_point){
    fur16 temp16,mask;
    fur8 bit_mask,operate;
    if((fur_cmd_buf[buf_point].status&FUR_EN)==0){
        return 0;
    }
    temp16  =fur_data_out(fur_cmd_buf[buf_point].addr);
    operate =(fur_cmd_buf[buf_point].operate)&0xF0;
    bit_mask=(fur_cmd_buf[buf_point].operate)&0x0F;
    switch(operate){
        case FUR_READ://���Ĵ�����
            //ɶ����������
        break;
        case FUR_ADD://�Ĵ�������һ������
            temp16+=fur_cmd_buf[buf_point].dat;
        break;
        case FUR_DEC://�Ĵ�����ȥһ������
            temp16-=fur_cmd_buf[buf_point].dat;
        break;
        case FUR_MUL://�Ĵ�������һ������
            temp16*=fur_cmd_buf[buf_point].dat;
        break;
        case FUR_DIV://�Ĵ�������һ������
            temp16/=fur_cmd_buf[buf_point].dat;
        break;
        case FUR_AND://�Ĵ�������һ������
            temp16&=fur_cmd_buf[buf_point].dat;
        break;
        case FUR_OR://�Ĵ�������һ������
            temp16|=fur_cmd_buf[buf_point].dat;
        break;
        case FUR_XOR://�Ĵ��������һ������
            temp16^=fur_cmd_buf[buf_point].dat;
        break;
        case FUR_BIT://�Ĵ���λ��ֵ��
            mask=1<<bit_mask;
            if(fur_cmd_buf[buf_point].dat){
                temp16|=mask;
            }else{
                temp16&=~mask;
            }
        break;
        case FUR_EQU://�Ĵ�����ֵ��
            temp16=fur_cmd_buf[buf_point].dat;
        break;
    }
    fur_data_in(fur_cmd_buf[buf_point].addr,temp16);
    fur_cmd_buf[buf_point].status|=FUR_END;
    return temp16;
}
/*-------------------------------------------------------
FUR��ʼ��������
-------------------------------------------------------*/
void fur_init(void){
    fur_status=0;
    fur_start =0;
    fur_end   =0;
    fur_count =0;
    fur_id    =0;
    fur_temp8 =0;
    fur_temp16=0;
}
/*-------------------------------------------------------
FUR����������
-------------------------------------------------------*/
void fur_deal(void){
    u16 temp16;
    while(fur_count){//�����ݻ�����ʱ��
        if(fur_count>FUR_BUF_MAX){
            fur_overflow_callback();
        }
        if(fur_cmd_buf[fur_start].status&FUR_FBID){
            #if FUR_UART_SEND_EN
                fur_set_uart('i');
                fur_set_uart('d');
                fur_set_uart('=');
                fur_send_num_10((u16)fur_get_id());
                fur_set_uart(';');
                fur_set_uart('\r');
                fur_set_uart('\n');
            #endif
        }else if(fur_cmd_buf[fur_start].status&FUR_WRITE){
            temp16=fur_reg_operate(fur_start);
            if(fur_cmd_buf[fur_start].status&FUR_END){
                #if FUR_UART_SEND_EN
                    fur_set_uart('(');
                    fur_send_num_10(fur_cmd_buf[fur_start].addr);
                    fur_set_uart(')');
                    fur_set_uart('=');
                    if(fur_cmd_buf[fur_start].status&FUR_HEX){
                        fur_set_uart('0');
                        fur_set_uart('x');
                        fur_send_num_16(temp16);
                    }else{
                        fur_send_num_10(temp16);
                    }
                    fur_set_uart(';');
                    fur_set_uart('\r');
                    fur_set_uart('\n');
                #endif
                fur_start++;
                if(fur_start>=FUR_BUF_MAX){//��ָ�����ĩ��ַ�Ļ���
                    fur_start=0;  //����ָ�롣
                }
            }
        }
        fur_count--;
    }
}
/*-------------------------------------------------------
FUR��麯����
-------------------------------------------------------*/
void fur_check(void){
    if((fur_id==0)||(fur_id==fur_get_id())){//�����Dz��ǹ㲥֡�����߷�������������֡��
        fur_cmd_buf[fur_end].status|=FUR_EN;//��ʹ��λ����������ȷʵ�ɱ�����������
        fur_end++;                          //βָ��+1��
        if(fur_end>=FUR_BUF_MAX){           //βָ�볬��ĩ��ַ�Ļ���
            fur_end=0;                      //����ָ�롣
        }
        fur_count++;                        //��������+1��
    }//����������������˵���������ݲ��Dz����������ͺ��Ե���
    fur_status=FUR_READY;                   //�ص�����״̬��
}
/*-------------------------------------------------------
FUR���ú�����
-------------------------------------------------------*/
void fur_reset(void){
    fur_status=FUR_GET_ADDR;        //���ú󵽽��յ�ַ״̬��
    fur_cmd_buf[fur_end].status=0;  //���״̬��
    fur_cmd_buf[fur_end].operate=0; //���������
    fur_cmd_buf[fur_end].addr=0;    //�����ַ��
    fur_cmd_buf[fur_end].dat=0;     //������ݡ�
    fur_temp16=0;                   //���16λ��ʱ������
    fur_temp8=0;                    //���8λ��ʱ������
}
/*-------------------------------------------------------
FUR���պ�����
-------------------------------------------------------*/
void fur_receive(void){
    fur8 dat;
    dat=fur_get_uart();
    switch(fur_status){
        case FUR_READY:{    //����״̬��
            //ɶҲ������
        }break;
        case FUR_GET_ADDR:{//���յ�ַ״̬��
            if((dat>='0')&&(dat<='9')){ //����յ�����0~9��
                fur_temp16*=10;         //�ճ�һλ��
                fur_temp16+=(dat-'0');  //���ַ�ת�������ַ���ճ�����һλ�ϡ�
            }else if(dat=='@'){         //��Ҫ�ǽ��յ�@��˵����ID���ݡ�
                fur_cmd_buf[fur_end].addr=fur_temp16;//����Ŀǰ���յ��ĵ�ַ��
                fur_id=0;               //ID�������㡣
                fur_status=FUR_GET_ID;  //��ת������ID״̬��
            }else if(dat==']'){         //����յ�]��˵����ַ�Ѿ�������ϡ�
                fur_cmd_buf[fur_end].addr=fur_temp16;//������յĵ�ַ��
                fur_id=0;               //ID�������㡣
                fur_status=FUR_GET_OP;  //��ת�����ղ���״̬��
            }else if((dat=='i')||(dat=='I')){//����յ���Сд��i�����ߴ�д��I��
                fur_id=0;               //ID�������㡣
                fur_status=FUR_CMD_ID;  //˵�������Dz�ID��ָ���ת����ID״̬��
            }else{                      //������յ������ַ���˵�����ճ����ˡ�
                fur_status=FUR_READY;   //�ص�����״̬��
            }
        }break;
        case FUR_CMD_ID:{//��ID״̬��
            if((dat=='d')||(dat=='D')){//�����״̬�£�ֻ�ж��Dz���ID�����Ǿ�����ȥ��
                fur_cmd_buf[fur_end].status|=FUR_FBID;//��λ��ѯID��
                fur_check();
            }
            fur_status=FUR_READY;   //�ص�����״̬��
        }break;
        case FUR_GET_ID:{//����ID״̬��
            if((dat>='0')&&(dat<='9')){ //����յ�����0~9��
                fur_id*=10;             //�ճ�һλ��
                fur_id+=(dat-'0');      //���ַ�ת�������ַ���ճ�����һλ�ϡ�
            }else if(dat==']'){         //����յ�]��˵��ID�Ѿ�������ϡ�
                fur_status=FUR_GET_OP;  //��ת�����ղ���״̬��
            }else{                      //������յ������ַ���˵�����ճ����ˡ�
                fur_status=FUR_READY;   //�ص�����״̬��
            }
        }break;
        case FUR_GET_OP:{//���ղ�����״̬��
            if(dat=='+'){               //����յ�+�ţ�
                fur_cmd_buf[fur_end].operate=FUR_ADD;//ִ�мӲ�����
                fur_status=FUR_GET_OP_EX;//������չ����״̬��
            }else if(dat=='-'){         //����յ�-�ţ�
                fur_cmd_buf[fur_end].operate=FUR_DEC;//ִ�м�������
                fur_status=FUR_GET_OP_EX;//������չ����״̬��
            }else if(dat=='*'){         //����յ�*�ţ�
                fur_cmd_buf[fur_end].operate=FUR_MUL;//ִ�г˲�����
                fur_status=FUR_GET_OP_EX;//������չ����״̬��
            }else if(dat=='/'){         //����յ�/�ţ�
                fur_cmd_buf[fur_end].operate=FUR_DIV;//ִ�г�������
                fur_status=FUR_GET_OP_EX;//������չ����״̬��
            }else if(dat=='&'){         //����յ�&�ţ�
                fur_cmd_buf[fur_end].operate=FUR_AND;//ִ���������
                fur_status=FUR_GET_OP_EX;//������չ����״̬��
            }else if(dat=='|'){         //����յ�|�ţ�
                fur_cmd_buf[fur_end].operate=FUR_OR;//ִ�л������
                fur_status=FUR_GET_OP_EX;//������չ����״̬��
            }else if(dat=='^'){         //����յ�^�ţ�
                fur_cmd_buf[fur_end].operate=FUR_XOR;//ִ����������
                fur_status=FUR_GET_OP_EX;//������չ����״̬��
            }else if(dat=='.'){         //����յ�.�ţ�
                fur_cmd_buf[fur_end].operate=FUR_BIT;//ִ��λ������
                fur_status=FUR_GET_OP_EX;//������չ����״̬��
            }else if(dat=='='){         //����յ�=�ţ�
                fur_cmd_buf[fur_end].operate=FUR_EQU;//ִ�и�ֵ������
                fur_temp16=0;           //���16λ��ʱ������
                fur_status=FUR_GET_DATA;//������������״̬��ʮ���ƣ���
            }else if(dat=='x'){         //����������յ�x��������ʮ�����ơ�
                fur_cmd_buf[fur_start].status|=FUR_HEX;//��λ��Ӧ�ı�־λ��������Ҫ��ת������״̬��
            }else if(dat=='?'){
                fur_cmd_buf[fur_end].operate=FUR_READ;//ִ�ж�ȡ������
                fur_check();            //�����յ�����Ϣ��
            }else{                      //������յ������ַ���˵�����ճ����ˡ�
                fur_status=FUR_READY;   //�ص�����״̬��
            }
            fur_temp8=0;                //���8λ��ʱ������
        }break;
        case FUR_GET_OP_EX:{//������չ����״̬��Ŀǰ���ǽ���λ������λ��ŵģ���
            if((dat>='0')&&(dat<='9')){ //����յ�����0~9��
                fur_temp8*=10;          //�ճ�һλ��
                fur_temp8+=(dat-'0');   //���ַ�ת�������ַ���ճ�����һλ�ϡ�
            }else if(dat=='='){         //����յ�=�ţ�
                fur_cmd_buf[fur_end].operate|=(fur_temp8&0x0F);//���Ƹò������ܳ���15��Ȼ�������������
                fur_temp16=0;           //���16λ��ʱ������
                fur_status=FUR_GET_DATA;//������������״̬��ʮ���ƣ���
            }else{                      //������յ������ַ���˵�����ճ����ˡ�
                fur_status=FUR_READY;   //�ص�����״̬��
            }
        }break;
        case FUR_GET_DATA:{//��������״̬��ʮ���ƣ���
            if((dat>='0')&&(dat<='9')){ //����յ�����0~9��
                fur_temp16*=10;         //�ճ�һλ��
                fur_temp16+=(dat-'0');  //���ַ�ת�������ַ���ճ�����һλ�ϡ�
            }else if(dat==';'){         //����յ���������
                fur_cmd_buf[fur_end].dat=fur_temp16;//�ѽ��յ����ݱ��棬
                fur_check();            //�����յ�����Ϣ��
            }else if((dat=='x')||(dat=='X')){//����յ�����x��˵������Ҫ�յ�16��������
                fur_temp16=0;           //���16λ��ʱ������
                fur_cmd_buf[fur_end].status|=FUR_HEX;//������ͨ����16���Ʊ�ʾ��
                fur_status=FUR_GET_DATA16;//������������״̬��ʮ�����ƣ���
            }else{                      //������յ������ַ���˵�����ճ����ˡ�
                fur_status=FUR_READY;   //�ص�����״̬��
            }
        }break;
        case FUR_GET_DATA16:{//��������״̬��ʮ�����ƣ���
            if((dat>='0')&&(dat<='9')){ //����յ�����0~9��
                fur_temp16*=16;         //�ճ�4bit��
                fur_temp16+=(dat-'0');  //���ַ�ת�������ַ���ճ���λ�ϡ�
            }else if((dat>='a')&&(dat<='f')){//����յ�����Сд����ĸ��
                fur_temp16*=16;         
                fur_temp16+=(dat-'a'+10);//������һ������ת���ַ���
            }else if((dat>='A')&&(dat<='F')){//����յ����Ǵ�д����ĸ��
                fur_temp16*=16;
                fur_temp16+=(dat-'A'+10);//������һ������ת���ַ���
            }else if(dat==';'){         //����յ���������
                fur_cmd_buf[fur_end].dat=fur_temp16;//�ѽ��յ����ݱ��棬
                fur_check();            //�����յ�����Ϣ��
            }else{                      //������յ������ַ���˵�����ճ����ˡ�
                fur_status=FUR_READY;   //�ص�����״̬��
            }
        }break;
    }
    if(dat=='['){                               //�κ�ʱ������յ��˿�ʼ���[��
        fur_reset();                            //�͵�������fur��
        fur_cmd_buf[fur_end].status|=FUR_WRITE; //�ٴ���д���־��
    }else if(dat=='('){                         //������յ��ظ����(��
        fur_reset();                            //ֻ����fur��
    }
}