Recovery

The best option for the first start up post-launch, is to fire the MCU and the entire board into recovery mode. The recovery mode, which will be described on its own page at a later point, will sit and wait for a signal from the ground to start up the payload etc., this is in case the payload malfunctions, so if the payload was to explode at least we would know that our lovely OBDH worked. So to enter the recovery mode, the PSU will have to supply power to the MCU, and the MCU will switch on the Coms, and then enter a low power state waiting for a signal from ground. On receiving the go ahead from the ground, the MCU will then start up the other systems, ADCS, Camera and Payload (in that order, with the payload being initiated last due to the potential difficulties in doing so), reporting back after each stage has been successfully completed - i.e. it will inform ground of the data from ADCS before initiating the Camera.

Below is the logic code of the recovery system, it is currently a work in progress, but this current version can be run through and it will only jump into the set mode when the bottom of the variable equals the right mode.

#define TEST
#define LTEST
#define T_STATE         0x1C00
#define FMemLocState    0x00
#define RMASK           0xFFF
#define RVALMASK        0xF000

#ifdef TEST
#include <stdio.h>
#else
#include <io.h>
#endif

void recover()
{
  /* the first thing we need to do is check the status of the state variable in our flash memory */
  /* the state variable could have the following values
   *http://www.wikidot.com/
   *     + mode          + decimal       + binary        + hex
   *     ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
   *    + idle          + 3             + 000000000011  + 0x3
   *    + recovery      + 12            + 000000001100  + 0xC
   *    + recieve       + 48            + 000000110000  + 0x30
   *    + transmit      + 192           + 000011000000  + 0xC0
   *    + payload       + 768           + 001100000000  + 0x300
   *    + store image   + 3072          + 110000000000  + 0xC00
   */
   /* we create a pointer and point it to the memory location of the variable in memory */
   #ifndef TEST
   unsigned short int* state=FMemLocState;
   #else
   unsigned short int* state;

   state=(unsigned short int*)malloc(2);
   if(state==0)
   {
     printf("Memory could not be allocated\n");
     return;
   }
   *state=T_STATE;
   #endif

   #ifdef LTEST
   for((*state)=0;(*state)<0xffff;(*state)++)
   {/*Recovery procedure for the satellite. This will be used when it first 
goes into orbit to start it up, and thereafter to recover it should something go wrong.*/
#define test
//Defines power level required to power up each subsystem, so that recover() knows if it can
//afford to power up each system. The values here at the moment are completely arbitrary
#define comspower 20
#define adcspower 15
#define cam_power 25
#define cardpower 5

#ifdef test
#include<stdio.h>
#else
#include<io.h>
#endif

int i2c_init()
{
#ifndef test
//Function to initialise I2C bus for use by check_psu()
U0CTL = 0x25; //Sets bits 1, 2 and 5 of the USART interface to 0 to enable I2C in master mode
I2COA = 0x0001; //Sets the address of the MCU on the bus to 1
#endif
return 1;
}

int check_psu()
{
//Function to read powerlevel from PSU
int powerlevel;
//code here assigns a value to power level after requesting it from the I2C bus
powerlevel = 100 ;
return powerlevel; //Return integer power level to the parent function
}

int powerup_coms() // Function to switch on coms. Returns boolean 1 or 0 for successful or not successful respectively
{
return 1;
}

int sd_init()
{
return 1;
}

int powerup_adcs()
{
return 0;
}

int powerup_camera()
{
return 1;
}

char recover()
{
    char status = 0x0; //creates a byte to hold the status of each subsystem as they are powered on
    if(!i2c_init())//Initialise the I2C bus so that check_psu can get a powerlevel
    {

        return status;
    }
    status |= 0x01;    
    int powerlevel;
    powerlevel = check_psu(); //Call check_psu and assign the value it returns to a variable "powerlevel"
    #ifdef test
    printf("Power level is %i \n", powerlevel);
    #endif
    if(powerlevel > comspower) //Find out of there is enough power to start coms
    {
        if(powerup_coms()) //If there is enough power, power up coms, check if the procedure was successful
        {
            status |= 0x02; //If coms powerup succeeded, set its status bit to 1. If not, it remains 0
            #ifdef test
            printf("Coms online\n");
            #endif
        }
    } //If the power level was not high enough, the status bit of the subsystem remains 0
    powerlevel = check_psu(); //Recheck the power level to ascertain an accurate value
    if(powerlevel > cardpower)
    {
        if(sd_init())
        {
            status |= 0x04;
            #ifdef test
            printf("SD online\n");
            #endif
        }
    }
    powerlevel = check_psu();
    if(powerlevel > adcspower)
    {
        if(powerup_adcs())
        {
            status |= 0x08;
            #ifdef test
            printf("ADCS online\n");
            #endif
        }
    }
    powerlevel = check_psu();
    if(powerlevel > cam_power)
    {
        if(powerup_camera())
        {
            status |= 0x10;
            #ifdef test
            printf("Camera online\n");
            #endif
        }
    }

    return status;
}

int main()
{
    //Code that goes in main to determine how successful recovery was
    char status = 0x000000;
    status = recover();
    #ifdef test
    printf("Status is %x ", (long)status & 0x0000ff );
    #endif
    return 0;
}
   #endif

   /* we then look at the variable and see what mode we are in */
   if(((*state)&RMASK)==0x3)/* idle */
   {
     #ifdef LTEST
     printf("State variable = %i (%#X)\n",(*state),(*state));
     #endif
     #ifdef TEST
     printf("idle\n");
     #endif
     /* make sure interrupts are enabled */
     /* shutdown/slowdown mcu to save power */
   }
   else if(((*state)&RMASK)==0xC)/* recovery */
   {
     /* You mite wonder why there is a recovery mode, as if the state is zero or any other value
      * it will default to recovery. Well this way we know more, in this part of the function
      * now we know that the cubesat has either messed up before and rebooted or we have some
      * other kind of fault */

     /* the top of the state variable, that is the top 4bits, are going to be used as a recovery
      * counter. There are 4 unused bits, which gives enough for us to count to 15; whcich will
      * be used to hold extra information about the number of times the mcu has been reset,
      * this could be useful, as knowing that the last 15 times we have tried to recover we have
      * crashed and restarted for some reason could be very useful and we will go into a super
      * recovery mode in which only coms are loaded, so we can decide what's the best action to
      * do from the ground */
     #ifdef LTEST
     printf("State variable = %i (%#X)\n",(*state),(*state));
     #endif
     #ifdef TEST
     printf("recovery\n");
     #endif

     /* check the variable to see how many times we have tried to recover */
     if(((*state)&RVALMASK)==0xF)
     {
       /* this means we have done the 15 tries */
       /* power up coms */
       /* wait for instructions */
       /* coms must have a facility to reset this variable */
     }
     else
     {
       /* we havn't got to the limit, so we increase the variable */
       /*(*state)+=(1<<12); method not working correctly, need way*/
       /* then we start the load up procedure */
       /* coms */
     }
  }
  else if(((*state)&RMASK)==0x30)/* recieve */
  {
    #ifdef LTEST
     printf("State variable = %i (%#X)\n",(*state),(*state));
    #endif
    #ifdef TEST
    printf("recieve\n");
    #endif
  }
  else if(((*state)&RMASK)==0xC0)/* transmit */
  {
    #ifdef LTEST
    printf("State variable = %i (%#X)\n",(*state),(*state));
    #endif
    #ifdef TEST
    printf("transmit\n");
    #endif
  }
  else if(((*state)&RMASK)==0x300)/* payload */
  {
    #ifdef LTEST
    printf("State variable = %i (%#X)\n",(*state),(*state));
    #endif
    #ifdef TEST
    printf("payload\n");
    #endif
  }
  else if(((*state)&RMASK)==0xC00)/* store image */
  {
    #ifdef LTEST
    printf("State variable = %i (%#X)\n",(*state),(*state));
    #endif
    #ifdef TEST
    printf("store image\n");
    #endifhttp://www.wikidot.com/
  }
  else /* start recovery */
  {
    /* welcome to what we hope is a very rare case of data corruption, or during the test
     * phase, mis-programming. In this case, what we will now do is a complete test of the
     * available memory, this will not include the sd card as it is not loaded into the
     * memory */
    #ifndef LTEST
    #ifdef TEST
    printf("start recovery\n");
    #endif
    #endif
  }
  #ifdef LTEST
  }
  #endif
}

#ifdef TEST
int main()
{
  recover();
  return 0;
}
#endif

The following code shows the current progress of the recovery procedure. The code does not currently produce the required results.

/*Recovery procedure for the satellite. This will be used when it first 
goes into orbit to start it up, and thereafter to recover it should something go wrong.*/
#define test
//Defines power level required to power up each subsystem, so that recover() knows if it can
//afford to power up each system. The values here at the moment are completely arbitrary
#define comspower 20
#define adcspower 15
#define cam_power 25
#define cardpower 5

#ifdef test
#include<stdio.h>
#else
#include<io.h>
#endif

int i2c_init()
{
#ifndef test
//Function to initialise I2C bus for use by check_psu()
U0CTL = 0x25; //Sets bits 1, 2 and 5 of the USART interface to 0 to enable I2C in master mode
I2COA = 0x0001; //Sets the address of the MCU on the bus to 1
#endif
return 1;
}

int check_psu()
{
//Function to read powerlevel from PSU
int powerlevel;
//code here assigns a value to power level after requesting it from the I2C bus
powerlevel = 100 ;
return powerlevel; //Return integer power level to the parent function
}

int powerup_coms() // Function to switch on coms. Returns boolean 1 or 0 for successful or not successful respectively
{
return 1;
}

int sd_init()
{
return 1;
}

int powerup_adcs()
{
return 0;
}

int powerup_camera()
{
return 1;
}

char recover()
{
    char status = 0x0; //creates a byte to hold the status of each subsystem as they are powered on
    if(!i2c_init())//Initialise the I2C bus so that check_psu can get a powerlevel
    {

        return status;
    }
    status |= 0x01;    
    int powerlevel;
    powerlevel = check_psu(); //Call check_psu and assign the value it returns to a variable "powerlevel"
    #ifdef test
    printf("Power level is %i \n", powerlevel);
    #endif
    if(powerlevel > comspower) //Find out of there is enough power to start coms
    {
        if(powerup_coms()) //If there is enough power, power up coms, check if the procedure was successful
        {
            status |= 0x02; //If coms powerup succeeded, set its status bit to 1. If not, it remains 0
            #ifdef test
            printf("Coms online\n");
            #endif
        }
    } //If the power level was not high enough, the status bit of the subsystem remains 0
    powerlevel = check_psu(); //Recheck the power level to ascertain an accurate value
    if(powerlevel > cardpower)
    {
        if(sd_init())
        {
            status |= 0x04;
            #ifdef test
            printf("SD online\n");
            #endif
        }
    }
    powerlevel = check_psu();
    if(powerlevel > adcspower)
    {
        if(powerup_adcs())
        {
            status |= 0x08;
            #ifdef test
            printf("ADCS online\n");
            #endif
        }
    }
    powerlevel = check_psu();
    if(powerlevel > cam_power)
    {
        if(powerup_camera())
        {
            status |= 0x10;
            #ifdef test
            printf("Camera online\n");
            #endif
        }
    }

    return status;
}

int main()
{
    //Code that goes in main to determine how successful recovery was
    char status = 0x000000;
    status = recover();
    #ifdef test
    printf("Status is %x ", (long)status & 0x0000ff );
    #endif
    return 0;
}
Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-Share Alike 2.5 License.