TELECOMMAND MANAGER V1

Dependencies:   mbed SLCD mbed-rtos

COM_RCV_TC.h

Committer:
shreeshas95
Date:
2015-07-06
Revision:
7:e71ecfe3a340
Parent:
6:6e9ae3b44e60
Child:
8:cb93c1d3209a

File content as of revision 7:e71ecfe3a340:

#include "stdio.h"
#include <cstdlib>
//sample data source instead of buffer//remove while interfacing with RX1M..add the logic to add data in read_byte function 
//have kept this slightly higher than actual//donno why gives error 


class RCV_TC{

private:
    uint16_t x;
    //counter for keeping count of data read
    TC_list *rcv_tc_head;
    unsigned char temp[135];
    
    TC_list *t_frame;
    TC_list *prev_frame;
    
    bool crc_pass;
    
    //this just converts a binary number to store in int variable, I am using while creating sample telecommands
    #define B(x) S_to_binary_(#x)
    static inline unsigned long long S_to_binary_(const char *s)
    {
        unsigned long long i = 0;
        while (*s) {
            i <<= 1;
            i += *s++ - '0';
        }
        return i;
    }
    
    void copy_bit(unsigned char* src_byte, unsigned char* dest_byte, unsigned char* count)
    {
        if (*src_byte & 0x80)
        {
            *dest_byte <<= 1;
            *dest_byte += 1;
        }
        else *dest_byte <<= 1;
        *src_byte <<= 1;
        (*count)++;
    }
    
    unsigned char read_byte(unsigned char* shift_in)
    {
        unsigned char byte;
        
        // byte = VAR_SPACE::data[x++];
        ++x;
        
        byte = VAR_SPACE::data_node->val;
        data_list *temp = VAR_SPACE::data_node->next;
        delete VAR_SPACE::data_node;
        VAR_SPACE::data_node = temp;
        
        if( x == 1 ){
            VAR_SPACE::head_data = new data_list;
            VAR_SPACE::rx_new_node = VAR_SPACE::head_data;
            VAR_SPACE::rx_new_node->next = NULL;
        }

        *shift_in = 0;
    
        return byte;
    }
    
    void attach_byte(unsigned char* a_byte, unsigned char* count, unsigned char* byte_no)
    {
        temp[(*byte_no)++] = *a_byte;
        *count = 0; 
    }
    
    void attach_frame(TC_list *t_frame, unsigned char* frame_no, unsigned char* byte_no)
    {
        t_frame = new TC_list;
        t_frame->next_TC = NULL;
        if(*frame_no == 0){
            rcv_tc_head = t_frame;
            prev_frame = rcv_tc_head;
        }
        else{
            prev_frame->next_TC = t_frame;
            prev_frame = t_frame;
        }
        prev_frame->TC_string = new unsigned char[*byte_no];
        for(int i = 0 ; i < *byte_no ; ++i){
            prev_frame->TC_string[i] = temp[i];
        }
        if(*byte_no == 11)
        {
            prev_frame->short_or_long = true;
        }
        
        *byte_no = 0;
        ++(*frame_no);
    }
    
    void scan_dstuff(unsigned char* fifo_byte, unsigned char* test_byte, unsigned char* flag, unsigned char* shift_in, unsigned char* dstuff_count)
    {
        if (*test_byte == 0x7E)//scan for flag
        {
            *flag = 2;
            return;
        }
        if (((*test_byte) & 0xFC) == 0xF8)//destuff
        {
            if (*shift_in == 8)
                *fifo_byte = read_byte(shift_in);
            copy_bit(fifo_byte, test_byte, shift_in);
            *test_byte = *test_byte | 0xF8;
            *dstuff_count = 4;
        }
    
    
    }
    void post_flag(unsigned char* a_byte, unsigned char* b_byte, unsigned char *shift_in)
    {
    
        for (int i = 0; i < 8; i++)
        {
            if (*shift_in == 8)         
            {
                *a_byte = read_byte(shift_in);
            }
            copy_bit(a_byte, b_byte, shift_in);
        }
    
    }
    void post_shift_out(unsigned char* fifo_byte, unsigned char* test_byte, unsigned char* shift_in)
    {
        if (*shift_in == 8)
            *fifo_byte = read_byte(shift_in);
        if (*fifo_byte & 0x80)
            *test_byte |= 0x01;
        (*shift_in)++;
        *fifo_byte <<= 1;
    }

    bool check_crc(unsigned char &byte_no)
    {
        uint16_t exp_crc = CRC::crc16_gen(temp, (byte_no - 2));
        uint16_t cal_crc = (temp[byte_no - 2] << 8) | temp[byte_no - 1];
        if (exp_crc == cal_crc)
        {
            return 1;
        }
        else
            return 0;
    }
    void check_last_frame(unsigned char* last_frame)
    {
        if (temp[1] & 0x20)
        {
            *last_frame = 1;
        }//considering 3rd bit of 2nd byte of packet as last bit flag
    }
    
public:    
    
    // Constructor
    RCV_TC(TC_list *HEAD){
        rcv_tc_head = HEAD;
        x = 0;
    }
    
    void RX_RCV_TC() 
    {
        x = 0;
        int count_down = 0;
        unsigned char test_byte = 0;
        unsigned char flag = 0;
        //flag = 0 ... scanning for 0x7E/searching for start of new frame
        //flag = 1 ... after detecting 0x7E, now start dstuffing , scanning for 7E, filling the fifo_byte if empty, attach the dstuff_byte  
        //flag = 2 ... detected 0x7E, check if the current t_frame is valid , then atttach the t_frame to p_frame   
        unsigned char fifo_byte = 0;
        unsigned char dstuff_byte = 0;
        unsigned char byte_no = 0;
        unsigned char frame_no = 0;
        unsigned char shift_in = 0, shift_out = 0; // flag to keep count of bytes shifted in/out of test byte
        unsigned char dstuff_count = 0;
        unsigned char last_frame = 0;
    
        //Processing starts here
        while (!last_frame)//process till last frame
        {
//            printf("inside last frame\r\n");
            while (flag == 0)
            {
                printf("entered flag 0\r\n");
                if (fifo_byte != 0x7E)//check for initial 0x7E, else discard and take next byte   //here I am checking byte wise instead of bitwise!!!
                {
                    count_down++;
                        
                    fifo_byte = read_byte(&shift_in); 
                    continue;
                }
                else
                {
                    count_down = 0;
                    flag = 1;
    
                    fifo_byte = read_byte(&shift_in);
                    post_flag(&fifo_byte, &test_byte, &shift_in);
                }
            }
            if (flag == 1)
            {
                for (; shift_in < 8;)//loop till all bits are written in test_byte from fifo_byte
                {
                    if (shift_out == 8)//if the bits written to dstuff_byte =8 
                    {
                        if (byte_no < 11)//if long frame-size hasn't reached, 
                            attach_byte(&dstuff_byte, &shift_out, &byte_no);//attach_byte to t_frame
                        else//else attach frame to the p_frame array
                        {
                            attach_frame(t_frame, &frame_no, &byte_no);
                            flag = 0;
                            post_flag(&fifo_byte, &test_byte, &shift_in);
                            dstuff_byte = 0;
                            break;
                        }
                    }
    
                    if (!(dstuff_count))
                        scan_dstuff(&fifo_byte, &test_byte, &flag, &shift_in, &dstuff_count);
                    else
                        dstuff_count--;//bcoz only 4th bit is being removed   //don't destuff for next four loops
                    if (flag == 2)
                        break;
                    copy_bit(&test_byte, &dstuff_byte, &shift_out);//shift_out
                    post_shift_out(&fifo_byte, &test_byte, &shift_in);//updating last bit of test_byte
                }
            }
            
            if (flag == 0)
                continue;
            if (shift_in == 8)
                fifo_byte = read_byte(&shift_in);
            if (flag == 2) // detected next 0x7E
            {
                if (shift_out % 8 == 0)//check if the t_frame is multiple of 8 else discard
                {
                    crc_pass = check_crc(byte_no);
                    if (crc_pass)
                    {
                        check_last_frame(&last_frame); //check if the current frame is last frame then set the last_frame flag
//                        b = byte_no;
                        attach_frame(t_frame, &frame_no, &byte_no); //then attach the t_frame to p_frame array 
                        flag = 1; //start scanning new frame
                        prev_frame->crc_pass=1;
                    }
                    else
                    {
                        check_last_frame(&last_frame); //need to put timer instead of this to avoid problems due to last_frame bit error            
//                        b = byte_no;
                        attach_frame(t_frame, &frame_no, &byte_no);
                        flag = 1;
                        prev_frame->crc_pass = 0;
                        shift_out = 0;
                    }
                }
                post_flag(&fifo_byte, &test_byte, &shift_in);
                dstuff_byte = 0;
            }
        }
        
        //RX end
        while(VAR_SPACE::data_node != NULL){
            data_list *temp = VAR_SPACE::data_node->next;
            delete VAR_SPACE::data_node;
            VAR_SPACE::data_node = temp; 
        }
    }
    
};