QITH FLAGS

Dependencies:   FreescaleIAP mbed-rtos mbed

Fork of TF_conops_BAE1_3 by Team Fox

main.cpp

Committer:
sakthipriya
Date:
2015-07-06
Revision:
1:7185136654ce
Parent:
0:246d1b5f11ae
Child:
2:3c6c33509772

File content as of revision 1:7185136654ce:

/************************************************************Header files*****************************************************************/

#include "mbed.h"
#include "rtos.h"
#include "pin_config.h"
#include "EPS.h"
#include "beacon.h"
#include "ACS.h"
#include "FreescaleIAP.h"           //required for r/w to flash

/***********************************************************For Testing - TO BE REMOVED***************************************************/

Serial pc(USBTX, USBRX);                    //for debugging purpose. will be removed along with printf
Timer t_exec;                               //To know the time of execution each thread
Timer t_start;                              //To know the time of entering  of each thread
Timer t_i2c_start;                          //To check the time sync in i2c communication
Timer t_i2c_exec;                           //To know the time taken by i2c read/write function

/**********************************************************configuring peripherals********************************************************/
I2CSlave slave(PIN1,PIN2);                                        //configuring pins as I2Cslave (sda ,scl)
InterruptIn irpt_4m_cdms(PIN97);                                      //I2c interrupt from CDMS
DigitalOut irpt_2_bae(PIN90);                                     //Sets interrupt to CDMS

extern PwmOut PWM1;
extern PwmOut PWM2;
extern PwmOut PWM3; 


/****************************************************global variables*********************************************************************/
// flags---------------------------------------------
uint32_t BAE_STATUS = 0x00000000;
uint32_t BAE_ENABLE = 0xFFFFFFFF;
//---------------------------------------------------
char hk_data[25];
extern SensorDataQuantised SensorQuantised;
/*****************************************************************Threads USed***********************************************************************************/
Thread *ptr_t_eps;
Thread *ptr_t_acs;
Thread *ptr_t_bea;
Thread *ptr_t_i2c;
//Thread *ptr_t_wdt;  


/**************************************************************funtion header**********************************************************************************/

void FCTN_HK_DATA_CATENATE();                   //combines hk structure into a string  


//---------------------------------------------------------------------------------------------------------------------------------------------------
//BEACON THREAD
//---------------------------------------------------------------------------------------------------------------------------------------------------

int beac_flag=0;                                                            //To receive telecommand from ground.

void T_BEA(void const *args)
{
    
    while(1)
    {
        Thread::signal_wait(0x3);
        printf("\n\rTHIS IS BEACON    %f\n\r",t_start.read());
        t_exec.start();
        FCTN_BEA_TX_MAIN();
        if(beac_flag==1)
        {
            Thread::wait(600000);
            beac_flag = 0;
        }
        t_exec.stop();
        printf("The time to execute beacon thread is %f seconds\n\r",t_exec.read());
        t_exec.reset();
    }
}
                                        


//---------------------------------------------------------------------------------------------------------------------------------------
//ACS THREAD
//---------------------------------------------------------------------------------------------------------------------------------------
int power_flag = 4;   //temporary dummy flag
int acs_pflag = 1;
void T_ACS(void const *args)
{
    float mag_field1[3];
    float omega1[3];
    //float tauc1[3];
    float moment[3];
    //float *mnm_data;
    while(1)
    {
        Thread::signal_wait(0x1);
        printf("\n\rEntered ACS   %f\n",t_start.read());
        t_exec.start();
        BAE_STATUS |= 0x00001000;     //set ACS_MAIN_STATUS flag to 1
        PWM1 = 0;                     //clear pwm pins
        PWM2 = 0;                     //clear pwm pins
        PWM3 = 0;                     //clear pwm pins
        //---------------------------------------
        omega1[0] = 1 ;           //for testing - to be removed
        omega1[1] = 2 ; 
        omega1[2] = 3 ; 
        mag_field1[0] = 10;
        mag_field1[1] = 20;
        mag_field1[2] = 30;
        //--------------------------------------
        if (BAE_ENABLE & 0x00000001 == 0x00000001)       // check if ACS_DATA_ACQ_ENABLE = 1?
        {
            FCTN_ACS_DATA_ACQ(omega1,mag_field1); 
            printf("\n\rmnm gyro values\n"); //printing the angular velocity and magnetic field values
            for(int i=0; i<3; i++) 
            {
                printf("%f\t",omega1[i]);
            }
            printf("\n\r mnm mag values\n");
            for(int i=0; i<3; i++) 
            {
                printf("%f\t",mag_field1[i]);
            }
        }
        if(BAE_ENABLE & 0x0000000E == 0x00000000)        // check ACS_STATE = ACS_CONTROL_OFF?
        {
            BAE_STATUS |= 0x00000000;                    // set ACS_STATUS = ACS_CONTROL_OFF
            PWM1 = 0;                     //clear pwm pins
            PWM2 = 0;                     //clear pwm pins
            PWM3 = 0;                     //clear pwm pins
        }
        else
        {
            if(power_flag > 1)
            {
                if(BAE_ENABLE & 0x0000000E == 0x00000004)   // check ACS_STATE = ACS_ZAXIS_MOMENT_ONLY 
                {
                    BAE_STATUS |= 0x00000018;                    // set ACS_STATUS = ACS_ZAXIS_MOMENT_ONLY   
                    FCTN_ACS_CNTRLALGO(mag_field1,omega1,moment);
                    printf("\n\r moment values returned by control algo \n");
                    moment[0] = 0;
                    moment[1] = 0;
                    printf("\n\r z axis moment %f \n",moment[2]);
                    FCTN_ACS_GENPWM_MAIN(moment) ;  
                } 
                else 
                {
                    if(BAE_ENABLE & 0x00000040 == 0x00000040)           // check ACS_STATE = ACS_DATA_ACQ_FAILURE
                    {
                        BAE_STATUS |= 0x0000000C;                    // set ACS_STATUS = ACS_DATA_ACQ_FAILURE
                        PWM1 = 0;                     //clear pwm pins
                        PWM2 = 0;                     //clear pwm pins
                        PWM3 = 0;                     //clear pwm pins
                    }
                    else
                    {
                        if(BAE_ENABLE & 0x0000000E == 0x00000008)       // check ACS_STATE = ACS_NOMINAL_ONLY
                        {
                            BAE_STATUS |= 0x00000010;                    // set ACS_STATUS = ACS_NOMINAL_ONLY
                            FCTN_ACS_CNTRLALGO(mag_field1,omega1,moment);
                            printf("\n\r moment values returned by control algo \n");
                            for(int i=0; i<3; i++) 
                            {
                                printf("%f\t",moment[i]);
                            }
                            FCTN_ACS_GENPWM_MAIN(moment) ;   
                        }
                        else
                        {
                            if(BAE_ENABLE & 0x0000000E == 0x0000000A)       // check ACS_STATE = ACS_AUTO_CONTROL
                            {
                                BAE_STATUS |= 0x00000014;                    // set ACS_STATUS = ACS_AUTO_CONTROL
                                //FCTN_ACS_AUTOCTRL_LOGIC                    // gotta include this code
                            }
                            else
                            {
                                if(BAE_ENABLE & 0x0000000E == 0x0000000C)       // check ACS_STATE = ACS_DETUMBLING_ONLY
                                {
                                    BAE_STATUS |= 0x00000018;                    // set ACS_STATUS = ACS_DETUMBLING_ONLY  
                                    FCTN_ACS_CNTRLALGO(mag_field1,omega1,moment);  // detumbling code has to be included
                                    FCTN_ACS_GENPWM_MAIN(moment) ; 
                                }
                                else
                                {
                                    BAE_STATUS |= 0x0000001C;                    // set ACS_STATUS = INVALID STATE 
                                    PWM1 = 0;                     //clear pwm pins
                                    PWM2 = 0;                     //clear pwm pins
                                    PWM3 = 0;                     //clear pwm pins
                                }
                            }
                        }
                    }   
                }
            }
            else
            {
                BAE_STATUS |= 0x00000004;                    // set ACS_STATUS = ACS_LOW_POWER
                PWM1 = 0;                     //clear pwm pins
                PWM2 = 0;                     //clear pwm pins
                PWM3 = 0;                     //clear pwm pins
            }
        } 
    
    BAE_STATUS &= 0xFFFFEFFF;     //clear ACS_MAIN_STATUS flag 
    t_exec.stop();
    printf("\n exited acs main %f ",t_exec.read());
    t_exec.reset();
    }
}

//--------------------------------------------------------------------------------------------------------------------------------------------------
//EPS THREAD
//--------------------------------------------------------------------------------------------------------------------------------------------------

void T_EPS(void const *args)
{
    
    while(1)
    {
        Thread::signal_wait(0x2);
        printf("\n\rTHIS IS EPS  %f\n\r",t_start.read());
        t_exec.start();
        BAE_STATUS |= 0x00040000;                    //set EPS_MAIN_STATUS flag
        FCTN_EPS_HK_MAIN() ;                         //Collecting HK data
        //FUNC_EPS_FAULTS();                         //Actual fault management is not implemented
        FCTN_EPS_BG_MAIN();                          //requesting soc and power mode         
        //FUNC_HK_POWER(SensorQuantised.power_mode); // !The power mode algorithm is yet to be obtained
        
        FCTN_HK_DATA_CATENATE();                                      //sending HK data to CDMS
        BAE_STATUS &= 0xFFFBFFFF;              //clear EPS_MAIN_STATUS flag
        t_exec.stop();
        printf("The time to execute hk_acq is %f seconds\n\r",t_exec.read());
        t_exec.reset();
    }
}

//---------------------------------------------------------------------------------------------------------------------------------------------------
//I2C THREAD
//---------------------------------------------------------------------------------------------------------------------------------------------------


//....................................................................................................................................

void FCTN_I2C_READ(char *data,int length = 1);
void FCTN_I2C_WRITE(char *data,int length = 1);

Timer t;                  // time taken from isr to reach i2c function
Timer t1;                 //time taken by read or write function in i2c function
Timer t2;                //time taken by read function when first command from master comes
bool write_ack = 1;
bool read_ack = 1;
char short_tc[10];
char long_tc[134];
char mstr_cmd;
bool cmd_flag = 1;
int length;
//char* data;
bool cmd_err = 1;


void T_I2C(void const * args)
{
     while(1)
    {
        Thread::signal_wait(0x1);
       // printf("\n\r check2\n");
        wait_us(100);
        
        if(cmd_flag == 1)
        {
            t.stop();
            if( slave.receive()==3 ||  slave.receive()==2)             // slave read 
            {
                
                t1.start();
                read_ack=slave.read(&mstr_cmd,1);
                t1.stop();
                if(read_ack == 0)
                printf("\n\r Data received from CDMS is %c \n",mstr_cmd);
                
                switch(mstr_cmd)
                {
                    case 's':
                    length = 10;
                    cmd_flag = 0;
                    break;
                    
                    
                    case 'l':
                    length = 134;
                    cmd_flag = 0;
                    break;
                    
                    case 'h':
                    length = 25;
                    cmd_flag = 0;
                    break;
                    
                    default:
                    printf("\n\r invalid command \n");
                    //cmd_err = 0;
                    cmd_flag = 1;
                }
                
                
            }   
        }
        else if(cmd_flag ==0 )
        {
            t.stop();
            if( slave.receive()==3 ||  slave.receive()==2)             // slave read 
            {
              
                char* data=(char*)malloc(length*sizeof(char));
                FCTN_I2C_READ(data,length);
                free(data); 
                cmd_flag = 1;
            }
            if( slave.receive() == 1)                                     // slave writes to master
            {
                FCTN_I2C_WRITE(hk_data,length );
                cmd_flag = 1;
            }
        }    
        printf("\n \r %d %d\n",t.read_us(),t1.read_us());
        t.reset();
        t1.reset(); 
        
      
    }
}

void FCTN_I2C_READ(char *data, int length )
{
    t1.start();
    read_ack=slave.read(data,length);
    t1.stop();
    if(read_ack == 0)
        printf("\n\rData received from CDMS is %s \n",data);
    else
        printf("\n\r data not received \n");
}

void FCTN_I2C_WRITE(char *data,int length)
{
    t1.start();
    write_ack=slave.write(data,length);
    t1.stop();       
    if(write_ack == 0)
        printf("\n\rData sent to CDMS is %s \n",data);
    else 
        printf("\n\r data not sent\n");
}
    
void FCTN_ISR_I2C()
{
     ptr_t_i2c->signal_set(0x1); 
     t.start();
}

void FCTN_HK_DATA_CATENATE()
{
        strcpy(hk_data,"hk_Data");
        strcat(hk_data,SensorQuantised.Voltage);
        strcat(hk_data,SensorQuantised.Current); 
        strcat(hk_data,SensorQuantised.Temperature);
        strcat(hk_data,SensorQuantised.AngularSpeed);
        strcat(hk_data,SensorQuantised.Bnewvalue);
        char fdata[5] = {SensorQuantised.BatteryTemperature,SensorQuantised.faultpoll,SensorQuantised.faultir,SensorQuantised.power_mode};
        /*strcat(hk_data,sfaultpoll);
        strcat(hk_data,sfaultir);
        strcat(hk_data,spower_mode);*/
        strcat(hk_data,fdata);
        printf("\n\r hk data being sent %s ",hk_data);
}
    

//------------------------------------------------------------------------------------------------------------------------------------------------
//SCHEDULER THREAD
//------------------------------------------------------------------------------------------------------------------------------------------------
int beacon_sc = 3;
uint8_t schedcount=1;
void T_SC(void const *args)
{    
    
   
    if(schedcount == 4)                         //to reset the counter
    {
        schedcount = 1;
    }
     printf("\n\rThe value of i in scheduler is %d\n\r",schedcount);
    if(schedcount%1==0)
    {
        ptr_t_acs -> signal_set(0x1);
    }
    
    if(schedcount%2==0)
    {
        ptr_t_eps -> signal_set(0x2);
        
    }
    if(schedcount%beacon_sc==0)
    {
        if(beac_flag==0)
        {
           ptr_t_bea -> signal_set(0x3);
        }
    }
    schedcount++;
}

//--------------------------------------------------------------BAE_INIT------------------------------------------------------------------//

void FCTN_BAE_INIT()
{
    BAE_STATUS |= 0x00000001;                             // set BAE_INIT_STATUS to 1
    irpt_4m_cdms.disable_irq();                           // disable interrupts
    slave.address(0x20);                                  // setting slave address for BAE for I2C communication
    RtosTimer t_sc_timer(T_SC,osTimerPeriodic);           // Initiating the scheduler thread - starting RTOS Timer
    t_sc_timer.start(10000);
    printf("\n\rStarted scheduler %f\n\r",t_start.read()); 
    FCTN_EPS_INIT();                                      // EPS INIT
    FCTN_ACS_INIT();                                      // ACS INIT
    FCTN_BEA_INIT();                                      // Beacon INIT
    //read bootup_count from flash
    //bootup_count++;
    //update bootup_count in flash
    irpt_4m_cdms.enable_irq();
    BAE_STATUS &= 0xFFFFFFFE;                             // clear BAE_INIT_STATUS to 0
}

    
//-------------------------------------------------------------------BAE_MAIN-------------------------------------------------------------//

int main()
{
    t_start.start();
    printf("\n\rIITMSAT BAE Activated \n");
    
    //INITIALISING THREADS
    ptr_t_eps = new Thread(T_EPS);
    ptr_t_acs = new Thread(T_ACS);                    
    ptr_t_bea = new Thread(T_BEA);
    ptr_t_i2c = new Thread(T_I2C);
    
    //INITIALISING INTERRUPTS
    //interrupt_fault();                                 //*to be included-function called when a fault interrupt is detected
    irpt_4m_cdms.fall(&FCTN_ISR_I2C);                       //interrupt received from CDMS
    
    //Setting priority to threads
    ptr_t_acs->set_priority(osPriorityAboveNormal);
    ptr_t_eps->set_priority(osPriorityAboveNormal);
    ptr_t_bea->set_priority(osPriorityAboveNormal);
    ptr_t_i2c->set_priority(osPriorityHigh);
  
    //----------------------------------------------------------------------------------------------
    printf("\n\r T_ACS priority is %d",ptr_t_acs->get_priority());
    printf("\n\r T_EPS priority is %d",ptr_t_eps->get_priority());
    printf("\n\r T_BEA priority is %d",ptr_t_bea->get_priority());
    printf("\n\r T_I2C priority is %d",ptr_t_i2c->get_priority());  
    //----------------------------------------------------------------------------------------------
    FCTN_BAE_INIT();
    while(1)                                                   //required to prevent main from terminating
    {   
        ;
    }
    
}