1518 lines
53 KiB
C
1518 lines
53 KiB
C
/*------------------------------------------------------------------------------
|
|
|
|
Copyright (C) 1998 : Space Systems Finland Ltd.
|
|
|
|
Space Systems Finland Ltd (SSF) allows you to use this version of
|
|
the DEBIE-I DPU software for the specific purpose and under the
|
|
specific conditions set forth in the Terms Of Use document enclosed
|
|
with or attached to this software. In particular, the software
|
|
remains the property of SSF and you must not distribute the software
|
|
to third parties without written and signed authorization from SSF.
|
|
|
|
System Name: DEBIE DPU SW
|
|
Subsystem : DAS
|
|
Module : tc_hand.c
|
|
|
|
Telecommand module.
|
|
|
|
Based on the SSF file tc_hand.c, rev 1.66, Thu Sep 09 13:29:18 1999.
|
|
|
|
- * --------------------------------------------------------------------------
|
|
*/
|
|
|
|
#include "keyword.h"
|
|
#include "kernobj.h"
|
|
#include "tm_data.h"
|
|
#include "isr_ctrl.h"
|
|
#include "msg_ctrl.h"
|
|
#include "tc_hand.h"
|
|
#include "telem.h"
|
|
#include "ttc_ctrl.h"
|
|
#include "measure.h"
|
|
#include "dpu_ctrl.h"
|
|
#include "health.h"
|
|
#include "class.h"
|
|
#include "taskctrl.h"
|
|
|
|
/* This file contains functions to implement Telecommand Execution Task */
|
|
|
|
#define TC_ADDRESS(TC_WORD) ((TC_WORD) >> 9)
|
|
#define TC_CODE(TC_WORD) ((TC_WORD) & 255)
|
|
|
|
#define SET_TIME_TC_TIMEOUT 100
|
|
/* Timeout between Set Time telecommands, 100 x 10ms = 1s */
|
|
|
|
#define MEM_BUFFER_SIZE 32
|
|
|
|
/* Possible TC look-up table values: */
|
|
|
|
#define ALL_INVALID 0
|
|
/* used for invalid TC addresses */
|
|
|
|
#define ALL_VALID 1
|
|
/* used for TCs which accept all TC codes */
|
|
|
|
#define ONLY_EQUAL 2
|
|
/* used for TCs which require equal TC address and code */
|
|
|
|
#define ON_OFF_TC 3
|
|
/* used for TCs which require ON, OFF or SELF_TEST parameter */
|
|
|
|
#define ONLY_EVEN 4
|
|
/* used currently only for SEND_STATUS_REGISTER TC */
|
|
|
|
|
|
#define WRITE_MEMORY_TIMEOUT 100
|
|
/* Timeout 100 x 10 ms = 1s. */
|
|
|
|
|
|
/* Array */
|
|
|
|
SU_settings_t EXTERNAL *EXTERNAL SU_config[ ] = {
|
|
&telemetry_data.sensor_unit_1,
|
|
&telemetry_data.sensor_unit_2,
|
|
&telemetry_data.sensor_unit_3,
|
|
&telemetry_data.sensor_unit_4
|
|
};
|
|
|
|
/* Type definitions */
|
|
|
|
typedef struct {
|
|
uint16_t TC_word; /* Received telecommand word */
|
|
unsigned char TC_address; /* Telecommand address */
|
|
unsigned char TC_code; /* Telecommand code */
|
|
} telecommand_t;
|
|
|
|
typedef enum {
|
|
code_e, data_e
|
|
} memory_type_t;
|
|
|
|
/* Global variables */
|
|
|
|
telecommand_t EXTERNAL previous_TC;
|
|
/* Holds previous telecommand unless a timeout has occurred */
|
|
|
|
unsigned char EXTERNAL TC_timeout = 0;
|
|
/* Time out for next telecommand, zero means no timeout */
|
|
|
|
|
|
unsigned char EXTERNAL TC_look_up[ 128 ];
|
|
/* Look-up table for all possible 128 TC address values */
|
|
|
|
TC_state_t EXTERNAL TC_state;
|
|
/* internal state of the Telecommand Execution task */
|
|
|
|
memory_type_t EXTERNAL memory_type;
|
|
/* Selection of memory write target (code/data) */
|
|
|
|
unsigned char EXTERNAL memory_transfer_buffer[ MEM_BUFFER_SIZE ];
|
|
/* Buffer for memory read and write telecommands */
|
|
|
|
unsigned char EXTERNAL address_MSB;
|
|
/* MSB of memory read source and write destination addresses */
|
|
|
|
unsigned char EXTERNAL address_LSB;
|
|
/* LSB of memory read source and write destination addresses. */
|
|
|
|
uint_least8_t EXTERNAL memory_buffer_index = 0;
|
|
/* Index to memory_buffer. */
|
|
|
|
unsigned char EXTERNAL write_checksum;
|
|
/* Checksum for memory write blocks. */
|
|
|
|
|
|
void InitTC_LookUp( void )
|
|
/* Purpose : Initializes the TC look-up table */
|
|
/* Interface : inputs - none */
|
|
/* outputs - TC_lool_up */
|
|
/* Preconditions : none */
|
|
/* Postconditions : TC_look_up is initialized */
|
|
/* Algorithm : - set all elements in table to ALL_INVALID */
|
|
/* - set each element corresponding valid TC address */
|
|
/* to proper value */
|
|
{
|
|
DIRECT_INTERNAL uint_least8_t i;
|
|
/* Loop variable */
|
|
|
|
|
|
_Pragma( "loopbound min 128 max 128" )
|
|
for ( i = 0; i < 128; i++ ) TC_look_up[ i ] = ALL_INVALID;
|
|
|
|
TC_look_up[ START_ACQUISITION ] = ONLY_EQUAL;
|
|
TC_look_up[ STOP_ACQUISITION ] = ONLY_EQUAL;
|
|
|
|
TC_look_up[ ERROR_STATUS_CLEAR ] = ONLY_EQUAL;
|
|
|
|
TC_look_up[ SEND_STATUS_REGISTER ] = ONLY_EVEN;
|
|
TC_look_up[ SEND_SCIENCE_DATA_FILE ] = ONLY_EQUAL;
|
|
|
|
TC_look_up[ SET_TIME_BYTE_0 ] = ALL_VALID;
|
|
TC_look_up[ SET_TIME_BYTE_1 ] = ALL_VALID;
|
|
TC_look_up[ SET_TIME_BYTE_2 ] = ALL_VALID;
|
|
TC_look_up[ SET_TIME_BYTE_3 ] = ALL_VALID;
|
|
|
|
TC_look_up[ SOFT_RESET ] = ONLY_EQUAL;
|
|
|
|
TC_look_up[ CLEAR_WATCHDOG_FAILURES ] = ONLY_EQUAL;
|
|
TC_look_up[ CLEAR_CHECKSUM_FAILURES ] = ONLY_EQUAL;
|
|
|
|
TC_look_up[ WRITE_CODE_MEMORY_MSB ] = ALL_VALID;
|
|
TC_look_up[ WRITE_CODE_MEMORY_LSB ] = ALL_VALID;
|
|
TC_look_up[ WRITE_DATA_MEMORY_MSB ] = ALL_VALID;
|
|
TC_look_up[ WRITE_DATA_MEMORY_LSB ] = ALL_VALID;
|
|
TC_look_up[ READ_DATA_MEMORY_MSB ] = ALL_VALID;
|
|
TC_look_up[ READ_DATA_MEMORY_LSB ] = ALL_VALID;
|
|
|
|
TC_look_up[ SWITCH_SU_1 ] = ON_OFF_TC;
|
|
TC_look_up[ SWITCH_SU_2 ] = ON_OFF_TC;
|
|
TC_look_up[ SWITCH_SU_3 ] = ON_OFF_TC;
|
|
TC_look_up[ SWITCH_SU_4 ] = ON_OFF_TC;
|
|
|
|
TC_look_up[ SET_SU_1_PLASMA_1P_THRESHOLD ] = ALL_VALID;
|
|
TC_look_up[ SET_SU_2_PLASMA_1P_THRESHOLD ] = ALL_VALID;
|
|
TC_look_up[ SET_SU_3_PLASMA_1P_THRESHOLD ] = ALL_VALID;
|
|
TC_look_up[ SET_SU_4_PLASMA_1P_THRESHOLD ] = ALL_VALID;
|
|
|
|
TC_look_up[ SET_SU_1_PLASMA_1M_THRESHOLD ] = ALL_VALID;
|
|
TC_look_up[ SET_SU_2_PLASMA_1M_THRESHOLD ] = ALL_VALID;
|
|
TC_look_up[ SET_SU_3_PLASMA_1M_THRESHOLD ] = ALL_VALID;
|
|
TC_look_up[ SET_SU_4_PLASMA_1M_THRESHOLD ] = ALL_VALID;
|
|
|
|
TC_look_up[ SET_SU_1_PIEZO_THRESHOLD ] = ALL_VALID;
|
|
TC_look_up[ SET_SU_2_PIEZO_THRESHOLD ] = ALL_VALID;
|
|
TC_look_up[ SET_SU_3_PIEZO_THRESHOLD ] = ALL_VALID;
|
|
TC_look_up[ SET_SU_4_PIEZO_THRESHOLD ] = ALL_VALID;
|
|
|
|
TC_look_up[ SET_SU_1_PLASMA_1P_CLASS_LEVEL ] = ALL_VALID;
|
|
TC_look_up[ SET_SU_2_PLASMA_1P_CLASS_LEVEL ] = ALL_VALID;
|
|
TC_look_up[ SET_SU_3_PLASMA_1P_CLASS_LEVEL ] = ALL_VALID;
|
|
TC_look_up[ SET_SU_4_PLASMA_1P_CLASS_LEVEL ] = ALL_VALID;
|
|
|
|
TC_look_up[ SET_SU_1_PLASMA_1M_CLASS_LEVEL ] = ALL_VALID;
|
|
TC_look_up[ SET_SU_2_PLASMA_1M_CLASS_LEVEL ] = ALL_VALID;
|
|
TC_look_up[ SET_SU_3_PLASMA_1M_CLASS_LEVEL ] = ALL_VALID;
|
|
TC_look_up[ SET_SU_4_PLASMA_1M_CLASS_LEVEL ] = ALL_VALID;
|
|
|
|
TC_look_up[ SET_SU_1_PLASMA_2P_CLASS_LEVEL ] = ALL_VALID;
|
|
TC_look_up[ SET_SU_2_PLASMA_2P_CLASS_LEVEL ] = ALL_VALID;
|
|
TC_look_up[ SET_SU_3_PLASMA_2P_CLASS_LEVEL ] = ALL_VALID;
|
|
TC_look_up[ SET_SU_4_PLASMA_2P_CLASS_LEVEL ] = ALL_VALID;
|
|
|
|
TC_look_up[ SET_SU_1_PIEZO_1_CLASS_LEVEL ] = ALL_VALID;
|
|
TC_look_up[ SET_SU_2_PIEZO_1_CLASS_LEVEL ] = ALL_VALID;
|
|
TC_look_up[ SET_SU_3_PIEZO_1_CLASS_LEVEL ] = ALL_VALID;
|
|
TC_look_up[ SET_SU_4_PIEZO_1_CLASS_LEVEL ] = ALL_VALID;
|
|
|
|
TC_look_up[ SET_SU_1_PIEZO_2_CLASS_LEVEL ] = ALL_VALID;
|
|
TC_look_up[ SET_SU_2_PIEZO_2_CLASS_LEVEL ] = ALL_VALID;
|
|
TC_look_up[ SET_SU_3_PIEZO_2_CLASS_LEVEL ] = ALL_VALID;
|
|
TC_look_up[ SET_SU_4_PIEZO_2_CLASS_LEVEL ] = ALL_VALID;
|
|
|
|
TC_look_up[ SET_SU_1_PLASMA_1E_1I_MAX_TIME ] = ALL_VALID;
|
|
TC_look_up[ SET_SU_2_PLASMA_1E_1I_MAX_TIME ] = ALL_VALID;
|
|
TC_look_up[ SET_SU_3_PLASMA_1E_1I_MAX_TIME ] = ALL_VALID;
|
|
TC_look_up[ SET_SU_4_PLASMA_1E_1I_MAX_TIME ] = ALL_VALID;
|
|
|
|
TC_look_up[ SET_SU_1_PLASMA_1E_PZT_MIN_TIME ] = ALL_VALID;
|
|
TC_look_up[ SET_SU_2_PLASMA_1E_PZT_MIN_TIME ] = ALL_VALID;
|
|
TC_look_up[ SET_SU_3_PLASMA_1E_PZT_MIN_TIME ] = ALL_VALID;
|
|
TC_look_up[ SET_SU_4_PLASMA_1E_PZT_MIN_TIME ] = ALL_VALID;
|
|
|
|
TC_look_up[ SET_SU_1_PLASMA_1E_PZT_MAX_TIME ] = ALL_VALID;
|
|
TC_look_up[ SET_SU_2_PLASMA_1E_PZT_MAX_TIME ] = ALL_VALID;
|
|
TC_look_up[ SET_SU_3_PLASMA_1E_PZT_MAX_TIME ] = ALL_VALID;
|
|
TC_look_up[ SET_SU_4_PLASMA_1E_PZT_MAX_TIME ] = ALL_VALID;
|
|
|
|
TC_look_up[ SET_SU_1_PLASMA_1I_PZT_MIN_TIME ] = ALL_VALID;
|
|
TC_look_up[ SET_SU_2_PLASMA_1I_PZT_MIN_TIME ] = ALL_VALID;
|
|
TC_look_up[ SET_SU_3_PLASMA_1I_PZT_MIN_TIME ] = ALL_VALID;
|
|
TC_look_up[ SET_SU_4_PLASMA_1I_PZT_MIN_TIME ] = ALL_VALID;
|
|
|
|
TC_look_up[ SET_SU_1_PLASMA_1I_PZT_MAX_TIME ] = ALL_VALID;
|
|
TC_look_up[ SET_SU_2_PLASMA_1I_PZT_MAX_TIME ] = ALL_VALID;
|
|
TC_look_up[ SET_SU_3_PLASMA_1I_PZT_MAX_TIME ] = ALL_VALID;
|
|
TC_look_up[ SET_SU_4_PLASMA_1I_PZT_MAX_TIME ] = ALL_VALID;
|
|
|
|
TC_look_up[ SET_COEFFICIENT_1 ] = ALL_VALID;
|
|
TC_look_up[ SET_COEFFICIENT_2 ] = ALL_VALID;
|
|
TC_look_up[ SET_COEFFICIENT_3 ] = ALL_VALID;
|
|
TC_look_up[ SET_COEFFICIENT_4 ] = ALL_VALID;
|
|
TC_look_up[ SET_COEFFICIENT_5 ] = ALL_VALID;
|
|
|
|
}
|
|
|
|
|
|
void TC_InterruptService ( void ) INTERRUPT( TC_ISR_SOURCE ) USED_REG_BANK( 2 )
|
|
/* Purpose : Handles the TC interrupt */
|
|
/* Interface : inputs - TC MSB and LSB hardware registers */
|
|
/* TC_look_up table giving valid TC addresses */
|
|
/* and TC codes */
|
|
/* outputs - TM data registers for received TC and TC */
|
|
/* time tag */
|
|
/* TM data registers for error and mode */
|
|
/* status */
|
|
/* TM MSB and LSB hardware registers */
|
|
/* telemetry_pointer */
|
|
/* telemetry_end_pointer */
|
|
/* Telecommand Execution task mailbox */
|
|
/* Preconditions : none */
|
|
/* Postconditions : */
|
|
/* Mail sent to Telecommand Execution task, if TC was */
|
|
/* valid */
|
|
/* Algorithm : - Read TC address and code from hardware registers */
|
|
/* - Calculate parity */
|
|
/* - If parity not Ok */
|
|
/* - Set parity error */
|
|
/* - Else */
|
|
/* - Clear parity error */
|
|
/* - Check TC address and code */
|
|
/* - If TC Ok */
|
|
/* Clear TC error and send mail */
|
|
/* - Else */
|
|
/* Set TC error */
|
|
/* - If TC is valid Send Status Register */
|
|
/* - Send first two registers defined by TC code */
|
|
/* - Else if TC is valid Send Science Data File */
|
|
/* - Send first teo bytes from Science Data File */
|
|
/* - Else if TC responce is enabled */
|
|
/* - Send Error Status and Mode Status */
|
|
/* - If TC is invalid */
|
|
/* - Disable TC responses */
|
|
|
|
{
|
|
DIRECT_INTERNAL unsigned char TC_address;
|
|
DIRECT_INTERNAL unsigned char TC_code;
|
|
DIRECT_INTERNAL uint16_t TC_word;
|
|
/* Telecommand and it's parts */
|
|
|
|
DIRECT_INTERNAL unsigned char par8, par4, par2, par1;
|
|
/* Parity calculation results */
|
|
|
|
DIRECT_INTERNAL unsigned char tmp_error_status;
|
|
/* Temporary result of TC validity check */
|
|
|
|
|
|
if ( !TC_TIMER_OVERFLOW_FLAG ) {
|
|
/* TC is rejected. */
|
|
|
|
telemetry_data.error_status |= TC_ERROR;
|
|
/* Set TC Error bit. */
|
|
|
|
return;
|
|
/* Abort ISR. */
|
|
}
|
|
|
|
if ( ( TC_state == SC_TM_e ) || ( TC_state == memory_dump_e ) ) {
|
|
return;
|
|
/* Abort ISR. */
|
|
}
|
|
|
|
STOP_TC_TIMER;
|
|
INIT_TC_TIMER_MSB;
|
|
INIT_TC_TIMER_LSB;
|
|
CLEAR_TC_TIMER_OVERFLOW_FLAG;
|
|
START_TC_TIMER;
|
|
|
|
TC_address = READ_TC_MSB;
|
|
TC_code = READ_TC_LSB;
|
|
TC_word = TC_address * 256 + TC_code;
|
|
/* Get TC Address, TC Code and TC Word */
|
|
|
|
if ( TC_state == memory_patch_e ) {
|
|
Send_ISR_Mail( 0, TC_word );
|
|
return;
|
|
/* This is not a normal telecommand, but word containing two bytes */
|
|
/* of memory block to be written to data or code memory. */
|
|
}
|
|
|
|
if ( TC_state == register_TM_e ) {
|
|
TC_state = TC_handling_e;
|
|
/* Register TM state is aborted */
|
|
|
|
ResetInterruptMask( TM_ISR_MASK );
|
|
/* Disable TM interrupt mask. Note that DisableInterrupt */
|
|
/* cannot be called from the C51 ISR. */
|
|
}
|
|
|
|
|
|
par8 = TC_address ^ TC_code;
|
|
par4 = ( par8 & 0x0F ) ^ ( par8 >> 4 );
|
|
par2 = ( par4 & 0x03 ) ^ ( par4 >> 2 );
|
|
par1 = ( par2 & 0x01 ) ^ ( par2 >> 1 );
|
|
/* Calculate parity */
|
|
|
|
TC_address >>= 1;
|
|
|
|
tmp_error_status = 0;
|
|
|
|
if ( par1 ) {
|
|
/* Parity error. */
|
|
|
|
tmp_error_status |= PARITY_ERROR;
|
|
}
|
|
|
|
else {
|
|
|
|
switch ( TC_look_up[ TC_address ] ) {
|
|
case ALL_INVALID:
|
|
/* Invalid TC Address */
|
|
tmp_error_status |= TC_ERROR;
|
|
break;
|
|
|
|
case ALL_VALID:
|
|
/* All TC Codes are valid */
|
|
Send_ISR_Mail( 0, TC_word );
|
|
break;
|
|
|
|
case ONLY_EQUAL:
|
|
/* TC Code should be equal to TC Address */
|
|
if ( TC_address != TC_code )
|
|
tmp_error_status |= TC_ERROR;
|
|
|
|
else
|
|
Send_ISR_Mail( 0, TC_word );
|
|
break;
|
|
|
|
case ON_OFF_TC:
|
|
/* TC_Code must have ON , OFF or SELF_TEST value */
|
|
if ( ( TC_code != ON_VALUE ) && ( TC_code != OFF_VALUE ) &&
|
|
( TC_code != SELF_TEST ) )
|
|
tmp_error_status |= TC_ERROR;
|
|
|
|
else
|
|
Send_ISR_Mail( 0, TC_word );
|
|
break;
|
|
|
|
case ONLY_EVEN:
|
|
/* TC_Code must be even and not too big */
|
|
if ( ( TC_code & 1 ) || ( TC_code > LAST_EVEN ) )
|
|
tmp_error_status |= TC_ERROR;
|
|
|
|
else
|
|
Send_ISR_Mail( 0, TC_word );
|
|
break;
|
|
}
|
|
}
|
|
|
|
if ( ( ( TC_address != SEND_STATUS_REGISTER )
|
|
|| ( tmp_error_status ) )
|
|
&& ( ( telemetry_data.error_status & TC_OR_PARITY_ERROR ) == 0 ) ) {
|
|
/* Condition 1 : */
|
|
/* (TC is not SEND STATUS REGISTER or TC is invalid). */
|
|
/* and condition 2: */
|
|
/* no invalid telecommands are recorded */
|
|
/* */
|
|
/* First condition checks that the Command Status and */
|
|
/* Command Time Tag registers should be updated. */
|
|
/* Second condition checks that the update can be done. */
|
|
|
|
|
|
telemetry_data.TC_word = TC_word;
|
|
COPY ( telemetry_data.TC_time_tag, internal_time );
|
|
/* Update TC registers in HK TM data area */
|
|
}
|
|
|
|
if ( tmp_error_status ) {
|
|
/* TC is invalid. */
|
|
|
|
telemetry_data.error_status |= tmp_error_status;
|
|
WRITE_TM_MSB ( telemetry_data.error_status );
|
|
WRITE_TM_LSB ( telemetry_data.mode_status );
|
|
/* Send response to this TC to TM */
|
|
|
|
return;
|
|
/* Abort ISR because TC is invalid. */
|
|
}
|
|
|
|
|
|
if ( TC_address == SEND_STATUS_REGISTER ) {
|
|
/* Send Status Register TC accepted */
|
|
|
|
COPY( telemetry_data.time, internal_time );
|
|
|
|
telemetry_pointer = ( ( EXTERNAL unsigned char * )&telemetry_data ) +
|
|
TC_code;
|
|
telemetry_end_pointer = ( ( EXTERNAL unsigned char * )&telemetry_data ) +
|
|
LAST_EVEN + 1;
|
|
/* First TM register to be sent is given in TC_Code */
|
|
|
|
CLEAR_TM_INTERRUPT_FLAG;
|
|
|
|
WRITE_TM_MSB ( *telemetry_pointer );
|
|
telemetry_pointer++;
|
|
WRITE_TM_LSB ( *telemetry_pointer );
|
|
telemetry_pointer++;
|
|
|
|
TC_state = register_TM_e;
|
|
|
|
SetInterruptMask( TM_ISR_MASK );
|
|
/* Enable TM interrupt mask. Note that EnableInterrupt */
|
|
/* cannot be called from the C51 ISR */
|
|
|
|
if ( telemetry_pointer > telemetry_end_pointer )
|
|
telemetry_pointer = ( EXTERNAL unsigned char * )&telemetry_data;
|
|
}
|
|
|
|
else
|
|
if ( TC_address == SEND_SCIENCE_DATA_FILE ) {
|
|
/* Send Science Data File TC accepted. */
|
|
|
|
if ( ( telemetry_data.mode_status & MODE_BITS_MASK ) == DPU_SELF_TEST ) {
|
|
/* Wrong DEBIE mode. */
|
|
|
|
telemetry_data.error_status |= TC_ERROR;
|
|
WRITE_TM_MSB ( telemetry_data.error_status );
|
|
WRITE_TM_LSB ( telemetry_data.mode_status );
|
|
/* Send response to this TC to TM. */
|
|
}
|
|
|
|
else {
|
|
telemetry_pointer = ( EXTERNAL unsigned char * )&science_data;
|
|
telemetry_end_pointer = ( ( EXTERNAL unsigned char * )
|
|
& ( science_data.event[ free_slot_index ] ) ) - 1;
|
|
/* Science telemetry stops to the end of the last used event */
|
|
/* record of the Science Data memory. */
|
|
|
|
science_data.length = ( unsigned short int )
|
|
( telemetry_end_pointer - telemetry_pointer + 1 ) / 2;
|
|
/* Store the current length of used science data. */
|
|
|
|
CLEAR_TM_INTERRUPT_FLAG;
|
|
|
|
WRITE_TM_MSB ( *telemetry_pointer );
|
|
telemetry_pointer++;
|
|
WRITE_TM_LSB ( *telemetry_pointer );
|
|
telemetry_pointer++;
|
|
|
|
TC_state = SC_TM_e;
|
|
|
|
SetInterruptMask( TM_ISR_MASK );
|
|
/* Enable TM interrupt mask. Note that EnableInterrupt */
|
|
/* cannot be called from a C51 ISR. */
|
|
}
|
|
}
|
|
|
|
else
|
|
if ( TC_address == READ_DATA_MEMORY_LSB ) {
|
|
/* Read Data Memory LSB accepted. */
|
|
|
|
if ( ( TC_state != read_memory_e ) ||
|
|
( ( ( unsigned int )address_MSB << 8 ) + TC_code
|
|
> ( END_SRAM3 - MEM_BUFFER_SIZE ) + 1 ) ) {
|
|
/* Wrong TC state or wrong address range. */
|
|
|
|
telemetry_data.error_status |= TC_ERROR;
|
|
WRITE_TM_MSB ( telemetry_data.error_status );
|
|
WRITE_TM_LSB ( telemetry_data.mode_status );
|
|
/* Send response to this TC to TM. */
|
|
|
|
TC_state = TC_handling_e;
|
|
}
|
|
|
|
else {
|
|
telemetry_pointer =
|
|
DATA_POINTER( ( int )address_MSB * 256 + TC_code );
|
|
telemetry_end_pointer = telemetry_pointer + MEM_BUFFER_SIZE;
|
|
|
|
CLEAR_TM_INTERRUPT_FLAG;
|
|
|
|
WRITE_TM_MSB ( telemetry_data.error_status );
|
|
WRITE_TM_LSB ( telemetry_data.mode_status );
|
|
/* First two bytes of Read Data Memory sequence. */
|
|
|
|
read_memory_checksum = tmp_error_status ^ telemetry_data.mode_status;
|
|
|
|
TC_state = memory_dump_e;
|
|
|
|
SetInterruptMask( TM_ISR_MASK );
|
|
}
|
|
}
|
|
|
|
else {
|
|
/* Some other TC accepted. */
|
|
|
|
WRITE_TM_MSB ( telemetry_data.error_status );
|
|
WRITE_TM_LSB ( telemetry_data.mode_status );
|
|
/* Send response to this TC to TM. */
|
|
}
|
|
|
|
}
|
|
|
|
|
|
unsigned char PatchExecCommandOk ( unsigned char execution_command )
|
|
{
|
|
switch ( execution_command ) {
|
|
case 0:
|
|
case 0x09:
|
|
case 0x37:
|
|
case 0x5A:
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
void MemoryPatch( telecommand_t EXTERNAL *command )
|
|
/* Purpose : Handles received telecommand in memory patch state */
|
|
/* Interface : inputs - command, received telecommand */
|
|
/* address_MSB, MSB of patch area */
|
|
/* address_LSB, LSB of patch area */
|
|
/* memory_transfer_buffer, buffer for bytes */
|
|
/* to be written to patch area */
|
|
/* memory_buffer_index, index to above buffer */
|
|
/* outputs - memory_transfer_buffer, as above */
|
|
/* memory_buffer_index, as above */
|
|
/* code_not_patched, indicates if code */
|
|
/* checksum is vali or not */
|
|
/* telemetry_data.mode_status, Mode Status */
|
|
/* telemetry register */
|
|
/* TC_state, TC Execution task state */
|
|
/* Preconditions : TC_state is memory patch. */
|
|
/* Destination memory type (data/code) is memorized. */
|
|
/* Postconditions : After last phase code or data memory patched if */
|
|
/* operation succeeded. */
|
|
/* Algorithm : - If memory_transfer_buffer not filled */
|
|
/* - update write_checksum (XOR with MSB and LSB of */
|
|
/* the telecommand word) */
|
|
/* - store TC word to memory_transfer_buffer */
|
|
/* - else */
|
|
/* - If checksum of TC block Ok */
|
|
/* - If data memory patch */
|
|
/* - copy memory_tranfer_buffer to data memory */
|
|
/* - else (code memory patch) */
|
|
/* - call PatchCode function */
|
|
/* - else */
|
|
/* - set MEMORY_WRITE_ERROR bit in ModeStatus */
|
|
|
|
{
|
|
memory_patch_variables_t EXTERNAL patch_info;
|
|
/* Parameters for PatchCode function. */
|
|
|
|
data_address_t INDIRECT_INTERNAL address;
|
|
/* Start address of the memory area to be patched. */
|
|
|
|
uint_least8_t INDIRECT_INTERNAL i;
|
|
/* Loop variable. */
|
|
|
|
unsigned char INDIRECT_INTERNAL TC_msb;
|
|
/* Most significant byte of the TC word. */
|
|
|
|
TC_msb = ( command -> TC_word ) >> 8;
|
|
write_checksum ^= TC_msb;
|
|
|
|
if ( memory_buffer_index < MEM_BUFFER_SIZE ) {
|
|
/* Filling the buffer bytes to be written to code or data */
|
|
/* memory. */
|
|
|
|
write_checksum ^= command -> TC_code;
|
|
|
|
memory_transfer_buffer[ memory_buffer_index ] = TC_msb;
|
|
memory_buffer_index++;
|
|
memory_transfer_buffer[ memory_buffer_index ] = command -> TC_code;
|
|
memory_buffer_index++;
|
|
|
|
TC_timeout = WRITE_MEMORY_TIMEOUT;
|
|
}
|
|
|
|
else {
|
|
/* Now all bytes for memory area to be patched have been */
|
|
/* received. */
|
|
|
|
if ( write_checksum == command -> TC_code ) {
|
|
/* Checksum Ok. */
|
|
|
|
address = ( ( unsigned int )address_MSB ) * 256 + address_LSB;
|
|
|
|
switch ( memory_type ) {
|
|
case data_e:
|
|
/* Write to the data memory. */
|
|
|
|
if ( address <= ( END_SRAM3 - MEM_BUFFER_SIZE + 1 ) ) {
|
|
_Pragma( "loopbound min 32 max 32" )
|
|
for ( i = 0; i < MEM_BUFFER_SIZE; i++ )
|
|
SET_DATA_BYTE( address + i, memory_transfer_buffer[ i ] );
|
|
}
|
|
|
|
else
|
|
Set_TC_Error();
|
|
|
|
break;
|
|
|
|
case code_e:
|
|
/* Write to the code memory. */
|
|
|
|
if ( ( address >= BEGIN_SRAM1 ) &&
|
|
( address <= END_SRAM1 - MEM_BUFFER_SIZE + 1 ) &&
|
|
( PatchExecCommandOk ( TC_msb ) ) )
|
|
|
|
{
|
|
/* Destination section resides in SRAM1. */
|
|
|
|
code_not_patched = 0;
|
|
/* Next code checksum not valid, because code memory */
|
|
/* will be patched. */
|
|
|
|
patch_info.source = memory_transfer_buffer,
|
|
patch_info.destination = address,
|
|
patch_info.data_amount = MEM_BUFFER_SIZE,
|
|
patch_info.execution_command = TC_msb;
|
|
/* Set parameters for the MemoryPatch function */
|
|
/* (see definition of memory_patch_variables_t). */
|
|
|
|
PatchCode( &patch_info );
|
|
/* May or may not return here. */
|
|
}
|
|
|
|
else {
|
|
/* Destination section out side SRAM1. */
|
|
Set_TC_Error();
|
|
}
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
else {
|
|
/* Checksum failure. */
|
|
|
|
SetModeStatusError( MEMORY_WRITE_ERROR );
|
|
/* Set memory write error bit in Mode Status register. */
|
|
}
|
|
|
|
TC_state = TC_handling_e;
|
|
}
|
|
}
|
|
|
|
|
|
void WriteMemory( telecommand_t EXTERNAL *command )
|
|
/* Purpose : Handles received telecommand in the WriteMemory state */
|
|
/* Interface : inputs - Parameter "command" containing received */
|
|
/* telecommand or memory byte */
|
|
/* memory_type defining code or data memory */
|
|
/* destination */
|
|
/* outputs - address_LSB, LSB of the patch area */
|
|
/* TC_state */
|
|
/* Preconditions : TC_state is write_memory */
|
|
/* Destination memory type (data/code) is memorized */
|
|
/* Postconditions : LSB of the patch area address is memorized. */
|
|
/* Algorithm : - update write_checksum (XOR with TC word MSB and LSB) */
|
|
/* - if telecommand is LSB setting of patch memory address */
|
|
/* of selected memory type */
|
|
/* - set TC state to memory_patch_e */
|
|
/* - memorize address LSB */
|
|
/* - clear memory_buffer_index */
|
|
/* - set TC timeout to WRITE_MEMORY_TIMEOUT */
|
|
/* - else */
|
|
/* - set TC state to TC_handling_e */
|
|
|
|
{
|
|
/* Expecting LSB of the start address for the memory area to be patched. */
|
|
|
|
write_checksum ^= ( ( command -> TC_word ) >> 8 ) ^ ( command -> TC_code );
|
|
|
|
if ( ( ( command -> TC_address == WRITE_CODE_MEMORY_LSB )
|
|
&& ( memory_type == code_e ) )
|
|
|| ( ( command -> TC_address == WRITE_DATA_MEMORY_LSB )
|
|
&& ( memory_type == data_e ) ) ) {
|
|
TC_state = memory_patch_e;
|
|
|
|
address_LSB = command -> TC_code;
|
|
memory_buffer_index = 0;
|
|
TC_timeout = WRITE_MEMORY_TIMEOUT;
|
|
}
|
|
|
|
else {
|
|
TC_state = TC_handling_e;
|
|
|
|
Set_TC_Error();
|
|
}
|
|
}
|
|
|
|
|
|
void UpdateTarget( telecommand_t EXTERNAL *command )
|
|
/* Purpose : Updates a HW register or some global variable according */
|
|
/* to the parameter "command" */
|
|
/* Interface : inputs - Parameter "command" containing received */
|
|
/* telecommand */
|
|
/* outputs - telemetry data */
|
|
/* Preconditions : The parameter "command" contains a valid telecommand */
|
|
/* Postconditions : A HW register or global variable is updated (depend on */
|
|
/* "command") */
|
|
/* Algorithm : - switch "command" */
|
|
/* - case Set Coefficient: */
|
|
/* set given quality coefficient value in telemetry */
|
|
/* according to "command" */
|
|
/* - case Min/Max Time: */
|
|
/* set Min/Max Time according to "command" */
|
|
/* - case Classification Level: */
|
|
/* set classification level according to "command" */
|
|
/* - case Error Status Clear: */
|
|
/* clear error indicating bits from telemetry */
|
|
/* - case Set Time Byte: */
|
|
/* set Debie time byte# according to "command" */
|
|
/* - case Clear Watchdog/Checksum Failure counter */
|
|
/* clear Watchdog/Checksum Failure counter */
|
|
/* - case Switch SU # On/Off/SelfTest */
|
|
/* switch SU to On/Off/SelfTest according to */
|
|
/* "command" */
|
|
/* - case Set Threshold */
|
|
/* set Threshold according to "command" */
|
|
{
|
|
EXTERNAL sensor_unit_t SU_setting;
|
|
/* Holds parameters for "SetSensorUnit" operation */
|
|
/* Must be in external memory, because the parameter to the function */
|
|
/* is pointer to external memory */
|
|
|
|
EXTERNAL trigger_set_t new_threshold;
|
|
|
|
dpu_time_t EXTERNAL new_time;
|
|
|
|
sensor_index_t EXTERNAL SU_index;
|
|
|
|
SU_index = ( ( command -> TC_address ) >> 4 ) - 2;
|
|
|
|
|
|
switch ( command -> TC_address ) {
|
|
case SET_COEFFICIENT_1:
|
|
case SET_COEFFICIENT_2:
|
|
case SET_COEFFICIENT_3:
|
|
case SET_COEFFICIENT_4:
|
|
case SET_COEFFICIENT_5:
|
|
|
|
telemetry_data.coefficient[ ( command -> TC_address ) & 0x07 ] =
|
|
command -> TC_code;
|
|
break;
|
|
|
|
case SET_SU_1_PLASMA_1E_1I_MAX_TIME:
|
|
case SET_SU_2_PLASMA_1E_1I_MAX_TIME:
|
|
case SET_SU_3_PLASMA_1E_1I_MAX_TIME:
|
|
case SET_SU_4_PLASMA_1E_1I_MAX_TIME:
|
|
|
|
SU_config[ SU_index ] -> plasma_1_plus_to_minus_max_time =
|
|
command -> TC_code;
|
|
break;
|
|
|
|
case SET_SU_1_PLASMA_1E_PZT_MIN_TIME:
|
|
case SET_SU_2_PLASMA_1E_PZT_MIN_TIME:
|
|
case SET_SU_3_PLASMA_1E_PZT_MIN_TIME:
|
|
case SET_SU_4_PLASMA_1E_PZT_MIN_TIME:
|
|
|
|
SU_config[ SU_index ] -> plasma_1_plus_to_piezo_min_time =
|
|
command -> TC_code;
|
|
break;
|
|
|
|
case SET_SU_1_PLASMA_1E_PZT_MAX_TIME:
|
|
case SET_SU_2_PLASMA_1E_PZT_MAX_TIME:
|
|
case SET_SU_3_PLASMA_1E_PZT_MAX_TIME:
|
|
case SET_SU_4_PLASMA_1E_PZT_MAX_TIME:
|
|
|
|
SU_config[ SU_index ] -> plasma_1_plus_to_piezo_max_time =
|
|
command -> TC_code;
|
|
break;
|
|
|
|
case SET_SU_1_PLASMA_1I_PZT_MIN_TIME:
|
|
case SET_SU_2_PLASMA_1I_PZT_MIN_TIME:
|
|
case SET_SU_3_PLASMA_1I_PZT_MIN_TIME:
|
|
case SET_SU_4_PLASMA_1I_PZT_MIN_TIME:
|
|
|
|
SU_config[ SU_index ] -> plasma_1_minus_to_piezo_min_time =
|
|
command -> TC_code;
|
|
break;
|
|
|
|
case SET_SU_1_PLASMA_1I_PZT_MAX_TIME:
|
|
case SET_SU_2_PLASMA_1I_PZT_MAX_TIME:
|
|
case SET_SU_3_PLASMA_1I_PZT_MAX_TIME:
|
|
case SET_SU_4_PLASMA_1I_PZT_MAX_TIME:
|
|
|
|
SU_config[ SU_index ] -> plasma_1_minus_to_piezo_max_time =
|
|
command -> TC_code;
|
|
break;
|
|
|
|
case SET_SU_1_PLASMA_1P_CLASS_LEVEL:
|
|
case SET_SU_2_PLASMA_1P_CLASS_LEVEL:
|
|
case SET_SU_3_PLASMA_1P_CLASS_LEVEL:
|
|
case SET_SU_4_PLASMA_1P_CLASS_LEVEL:
|
|
|
|
SU_config[ SU_index ] -> plasma_1_plus_classification =
|
|
command -> TC_code;
|
|
break;
|
|
|
|
case SET_SU_1_PLASMA_1M_CLASS_LEVEL:
|
|
case SET_SU_2_PLASMA_1M_CLASS_LEVEL:
|
|
case SET_SU_3_PLASMA_1M_CLASS_LEVEL:
|
|
case SET_SU_4_PLASMA_1M_CLASS_LEVEL:
|
|
|
|
SU_config[ SU_index ] -> plasma_1_minus_classification =
|
|
command -> TC_code;
|
|
break;
|
|
|
|
case SET_SU_1_PLASMA_2P_CLASS_LEVEL:
|
|
case SET_SU_2_PLASMA_2P_CLASS_LEVEL:
|
|
case SET_SU_3_PLASMA_2P_CLASS_LEVEL:
|
|
case SET_SU_4_PLASMA_2P_CLASS_LEVEL:
|
|
|
|
SU_config[ SU_index ] -> plasma_2_plus_classification =
|
|
command -> TC_code;
|
|
break;
|
|
|
|
case SET_SU_1_PIEZO_1_CLASS_LEVEL:
|
|
case SET_SU_2_PIEZO_1_CLASS_LEVEL:
|
|
case SET_SU_3_PIEZO_1_CLASS_LEVEL:
|
|
case SET_SU_4_PIEZO_1_CLASS_LEVEL:
|
|
|
|
SU_config[ SU_index ] -> piezo_1_classification =
|
|
command -> TC_code;
|
|
break;
|
|
|
|
case SET_SU_1_PIEZO_2_CLASS_LEVEL:
|
|
case SET_SU_2_PIEZO_2_CLASS_LEVEL:
|
|
case SET_SU_3_PIEZO_2_CLASS_LEVEL:
|
|
case SET_SU_4_PIEZO_2_CLASS_LEVEL:
|
|
|
|
SU_config[ SU_index ] -> piezo_2_classification =
|
|
command -> TC_code;
|
|
break;
|
|
|
|
case ERROR_STATUS_CLEAR:
|
|
|
|
ClearErrorStatus();
|
|
Clear_RTX_Errors();
|
|
ClearSoftwareError();
|
|
ClearModeStatusError();
|
|
Clear_SU_Error();
|
|
/* Clear Error Status register, RTX and software error indicating bits */
|
|
/* and Mode and SU Status registers. */
|
|
|
|
break;
|
|
|
|
|
|
case SET_TIME_BYTE_3:
|
|
|
|
new_time = ( ( dpu_time_t ) command -> TC_code ) << 24;
|
|
COPY ( internal_time, new_time );
|
|
TC_timeout = SET_TIME_TC_TIMEOUT;
|
|
|
|
break;
|
|
|
|
case SET_TIME_BYTE_2:
|
|
|
|
if ( previous_TC.TC_address == SET_TIME_BYTE_3 ) {
|
|
COPY ( new_time, internal_time );
|
|
|
|
new_time &= 0xFF000000;
|
|
new_time |=
|
|
( ( dpu_time_t ) command -> TC_code ) << 16;
|
|
|
|
COPY ( internal_time, new_time );
|
|
|
|
TC_timeout = SET_TIME_TC_TIMEOUT;
|
|
}
|
|
|
|
else
|
|
Set_TC_Error();
|
|
|
|
break;
|
|
|
|
case SET_TIME_BYTE_1:
|
|
|
|
if ( previous_TC.TC_address == SET_TIME_BYTE_2 ) {
|
|
COPY ( new_time, internal_time );
|
|
|
|
new_time &= 0xFFFF0000;
|
|
new_time |=
|
|
( ( dpu_time_t ) command -> TC_code ) << 8;
|
|
|
|
COPY ( internal_time, new_time );
|
|
|
|
TC_timeout = SET_TIME_TC_TIMEOUT;
|
|
}
|
|
|
|
else
|
|
Set_TC_Error();
|
|
|
|
break;
|
|
|
|
case SET_TIME_BYTE_0:
|
|
|
|
if ( previous_TC.TC_address == SET_TIME_BYTE_1 ) {
|
|
COPY ( new_time, internal_time );
|
|
|
|
new_time &= 0xFFFFFF00;
|
|
new_time |=
|
|
( ( dpu_time_t ) command -> TC_code );
|
|
|
|
COPY ( internal_time, new_time );
|
|
}
|
|
|
|
else
|
|
Set_TC_Error();
|
|
|
|
break;
|
|
|
|
case CLEAR_WATCHDOG_FAILURES:
|
|
|
|
telemetry_data.watchdog_failures = 0;
|
|
break;
|
|
|
|
case CLEAR_CHECKSUM_FAILURES:
|
|
|
|
telemetry_data.checksum_failures = 0;
|
|
break;
|
|
|
|
case SWITCH_SU_1:
|
|
case SWITCH_SU_2:
|
|
case SWITCH_SU_3:
|
|
case SWITCH_SU_4:
|
|
|
|
if ( GetMode() != ACQUISITION ) {
|
|
SU_setting.SU_number = SU_index + SU_1;
|
|
|
|
switch ( command -> TC_code ) {
|
|
case ON_VALUE:
|
|
Start_SU_SwitchingOn( SU_index, &
|
|
( SU_setting.execution_result ) );
|
|
break;
|
|
|
|
case OFF_VALUE:
|
|
SetSensorUnitOff( SU_index, &( SU_setting.execution_result ) );
|
|
break;
|
|
|
|
case SELF_TEST:
|
|
SU_setting.SU_state = self_test_mon_e;
|
|
SU_setting.expected_source_state = on_e;
|
|
Switch_SU_State ( &SU_setting );
|
|
break;
|
|
}
|
|
|
|
if ( SU_setting.execution_result == SU_STATE_TRANSITION_FAILED ) {
|
|
/* The requested SU state transition failed. */
|
|
|
|
Set_TC_Error();
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
Set_TC_Error();
|
|
|
|
break;
|
|
|
|
case SET_SU_1_PLASMA_1P_THRESHOLD:
|
|
|
|
new_threshold.sensor_unit = SU_1;
|
|
new_threshold.channel = PLASMA_1_PLUS;
|
|
new_threshold.level = command -> TC_code;
|
|
SetTriggerLevel( &new_threshold );
|
|
|
|
telemetry_data.sensor_unit_1.plasma_1_plus_threshold =
|
|
command -> TC_code;
|
|
break;
|
|
|
|
case SET_SU_2_PLASMA_1P_THRESHOLD:
|
|
|
|
new_threshold.sensor_unit = SU_2;
|
|
new_threshold.channel = PLASMA_1_PLUS;
|
|
new_threshold.level = command -> TC_code;
|
|
SetTriggerLevel( &new_threshold );
|
|
|
|
telemetry_data.sensor_unit_2.plasma_1_plus_threshold =
|
|
command -> TC_code;
|
|
break;
|
|
|
|
case SET_SU_3_PLASMA_1P_THRESHOLD:
|
|
|
|
new_threshold.sensor_unit = SU_3;
|
|
new_threshold.channel = PLASMA_1_PLUS;
|
|
new_threshold.level = command -> TC_code;
|
|
SetTriggerLevel( &new_threshold );
|
|
|
|
telemetry_data.sensor_unit_3.plasma_1_plus_threshold =
|
|
command -> TC_code;
|
|
break;
|
|
|
|
case SET_SU_4_PLASMA_1P_THRESHOLD:
|
|
|
|
new_threshold.sensor_unit = SU_4;
|
|
new_threshold.channel = PLASMA_1_PLUS;
|
|
new_threshold.level = command -> TC_code;
|
|
SetTriggerLevel( &new_threshold );
|
|
|
|
telemetry_data.sensor_unit_4.plasma_1_plus_threshold =
|
|
command -> TC_code;
|
|
break;
|
|
|
|
case SET_SU_1_PLASMA_1M_THRESHOLD:
|
|
|
|
new_threshold.sensor_unit = SU_1;
|
|
new_threshold.channel = PLASMA_1_MINUS;
|
|
new_threshold.level = command -> TC_code;
|
|
SetTriggerLevel( &new_threshold );
|
|
|
|
telemetry_data.sensor_unit_1.plasma_1_minus_threshold =
|
|
command -> TC_code;
|
|
break;
|
|
|
|
case SET_SU_2_PLASMA_1M_THRESHOLD:
|
|
|
|
new_threshold.sensor_unit = SU_2;
|
|
new_threshold.channel = PLASMA_1_MINUS;
|
|
new_threshold.level = command -> TC_code;
|
|
SetTriggerLevel( &new_threshold );
|
|
|
|
telemetry_data.sensor_unit_2.plasma_1_minus_threshold =
|
|
command -> TC_code;
|
|
break;
|
|
|
|
case SET_SU_3_PLASMA_1M_THRESHOLD:
|
|
|
|
new_threshold.sensor_unit = SU_3;
|
|
new_threshold.channel = PLASMA_1_MINUS;
|
|
new_threshold.level = command -> TC_code;
|
|
SetTriggerLevel( &new_threshold );
|
|
|
|
telemetry_data.sensor_unit_3.plasma_1_minus_threshold =
|
|
command -> TC_code;
|
|
break;
|
|
|
|
case SET_SU_4_PLASMA_1M_THRESHOLD:
|
|
|
|
new_threshold.sensor_unit = SU_4;
|
|
new_threshold.channel = PLASMA_1_MINUS;
|
|
new_threshold.level = command -> TC_code;
|
|
SetTriggerLevel( &new_threshold );
|
|
|
|
telemetry_data.sensor_unit_4.plasma_1_minus_threshold =
|
|
command -> TC_code;
|
|
break;
|
|
|
|
case SET_SU_1_PIEZO_THRESHOLD:
|
|
|
|
new_threshold.sensor_unit = SU_1;
|
|
new_threshold.channel = PZT_1_2;
|
|
new_threshold.level = command -> TC_code;
|
|
SetTriggerLevel( &new_threshold );
|
|
|
|
telemetry_data.sensor_unit_1.piezo_threshold = command -> TC_code;
|
|
break;
|
|
|
|
case SET_SU_2_PIEZO_THRESHOLD:
|
|
|
|
new_threshold.sensor_unit = SU_2;
|
|
new_threshold.channel = PZT_1_2;
|
|
new_threshold.level = command -> TC_code;
|
|
SetTriggerLevel( &new_threshold );
|
|
|
|
telemetry_data.sensor_unit_2.piezo_threshold = command -> TC_code;
|
|
break;
|
|
|
|
case SET_SU_3_PIEZO_THRESHOLD:
|
|
|
|
new_threshold.sensor_unit = SU_3;
|
|
new_threshold.channel = PZT_1_2;
|
|
new_threshold.level = command -> TC_code;
|
|
SetTriggerLevel( &new_threshold );
|
|
|
|
telemetry_data.sensor_unit_3.piezo_threshold = command -> TC_code;
|
|
break;
|
|
|
|
case SET_SU_4_PIEZO_THRESHOLD:
|
|
|
|
new_threshold.sensor_unit = SU_4;
|
|
new_threshold.channel = PZT_1_2;
|
|
new_threshold.level = command -> TC_code;
|
|
SetTriggerLevel( &new_threshold );
|
|
|
|
telemetry_data.sensor_unit_4.piezo_threshold = command -> TC_code;
|
|
break;
|
|
|
|
default:
|
|
/* Telecommands that will not be implemented in the Prototype SW */
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
void ExecuteCommand( telecommand_t EXTERNAL *command )
|
|
/* Purpose : Executes telecommand */
|
|
/* Interface : inputs - Parameter "command" containing received */
|
|
/* telecommand */
|
|
/* outputs - TC_state */
|
|
/* address_MSB */
|
|
/* memory_type */
|
|
/* subroutines - UpdateTarget */
|
|
/* StartAcquisition */
|
|
/* StopAcquisition */
|
|
/* SoftReset */
|
|
/* Set_TC_Error */
|
|
/* Switch_SU_State */
|
|
/* Reboot */
|
|
/* SetMode */
|
|
/* UpdateTarget */
|
|
/* Preconditions : The parameter "command" contains a valid telecommand */
|
|
/* TC_state is TC_handling */
|
|
/* Postconditions : Telecommand is executed */
|
|
/* TC_state updated when appropriate (depend on "command") */
|
|
/* HW registers modified when appropriate (depend on */
|
|
/* "command") */
|
|
/* Global variables modified when appropriate (depend on */
|
|
/* "command") */
|
|
/* Algorithm : - switch "command" */
|
|
/* - case Send Sciece Data File : set TC_state to SC_TM */
|
|
/* - case Send Status Register : set TC_state to */
|
|
/* RegisterTM */
|
|
/* - case Read Data Memory MSB : memorize the address */
|
|
/* MSB given in the TC_code and set TC_state to */
|
|
/* read_memory */
|
|
/* - case Write Code Memory MSB : memorize the address */
|
|
/* MSB given in the TC_code, memorize code */
|
|
/* destination selection and set TC_state to */
|
|
/* write_memory */
|
|
/* - case Write Data Memory MSB : memorize the address */
|
|
/* MSB given in the TC_code, memorize data */
|
|
/* destination selection and set TC_state to */
|
|
/* write_memory */
|
|
/* - case Read/Write Memory LSB : ignore telecommand */
|
|
/* - case Soft Reset : call SoftReset */
|
|
/* - case Start Acquisition : call StartAcquisition */
|
|
/* - case Stop Acquisition : call StopAcquisition */
|
|
/* - default : call UpdateTarget */
|
|
|
|
{
|
|
sensor_unit_t EXTERNAL SU_setting;
|
|
unsigned char error_flag;
|
|
sensor_number_t i;
|
|
|
|
switch ( command -> TC_address ) {
|
|
case SEND_SCIENCE_DATA_FILE:
|
|
break;
|
|
|
|
case SEND_STATUS_REGISTER:
|
|
break;
|
|
|
|
case READ_DATA_MEMORY_MSB:
|
|
address_MSB = command -> TC_code;
|
|
TC_state = read_memory_e;
|
|
break;
|
|
|
|
case WRITE_CODE_MEMORY_MSB:
|
|
if ( GetMode() == STAND_BY ) {
|
|
address_MSB = command -> TC_code;
|
|
memory_type = code_e;
|
|
TC_timeout = WRITE_MEMORY_TIMEOUT;
|
|
write_checksum =
|
|
( ( command -> TC_word ) >> 8 ) ^ ( command -> TC_code );
|
|
TC_state = write_memory_e;
|
|
}
|
|
|
|
else
|
|
Set_TC_Error();
|
|
|
|
break;
|
|
|
|
case WRITE_DATA_MEMORY_MSB:
|
|
if ( GetMode() == STAND_BY ) {
|
|
address_MSB = command -> TC_code;
|
|
memory_type = data_e;
|
|
TC_timeout = WRITE_MEMORY_TIMEOUT;
|
|
write_checksum =
|
|
( ( command -> TC_word ) >> 8 ) ^ ( command -> TC_code );
|
|
TC_state = write_memory_e;
|
|
}
|
|
|
|
else
|
|
Set_TC_Error();
|
|
|
|
break;
|
|
|
|
case READ_DATA_MEMORY_LSB:
|
|
break;
|
|
|
|
case WRITE_CODE_MEMORY_LSB:
|
|
case WRITE_DATA_MEMORY_LSB:
|
|
if ( TC_state != write_memory_e )
|
|
Set_TC_Error();
|
|
break;
|
|
|
|
case SOFT_RESET:
|
|
Reboot( soft_reset_e );
|
|
/* Software is rebooted, no return to this point. */
|
|
|
|
break;
|
|
|
|
case START_ACQUISITION:
|
|
error_flag = 0;
|
|
|
|
_Pragma( "loopbound min 4 max 4" )
|
|
for ( i = SU_1; i <= SU_4; i++ ) {
|
|
if ( ( ReadSensorUnit( i ) == start_switching_e ) ||
|
|
( ReadSensorUnit( i ) == switching_e ) ) {
|
|
/* SU is being switched on. */
|
|
|
|
error_flag = 1;
|
|
/* StartAcquisition TC has to be rejected. */
|
|
}
|
|
}
|
|
|
|
if ( ( GetMode() == STAND_BY ) && ( error_flag == 0 ) ) {
|
|
SU_setting.SU_state = acquisition_e;
|
|
SU_setting.expected_source_state = on_e;
|
|
|
|
SU_setting.SU_number = SU_1;
|
|
Switch_SU_State ( &SU_setting );
|
|
/* Try to switch SU 1 to Acquisition state. */
|
|
|
|
SU_setting.SU_number = SU_2;
|
|
Switch_SU_State ( &SU_setting );
|
|
/* Try to switch SU 2 to Acquisition state. */
|
|
|
|
SU_setting.SU_number = SU_3;
|
|
Switch_SU_State ( &SU_setting );
|
|
/* Try to switch SU 3 to Acquisition state. */
|
|
|
|
SU_setting.SU_number = SU_4;
|
|
Switch_SU_State ( &SU_setting );
|
|
/* Try to switch SU 4 to Acquisition state. */
|
|
|
|
CLEAR_HIT_TRIGGER_ISR_FLAG;
|
|
|
|
ResetDelayCounters();
|
|
/* Resets the SU logic that generates Hit Triggers. */
|
|
/* Brings T2EX to a high level, making a new falling */
|
|
/* edge possible. */
|
|
/* This statement must come after the above "clear", */
|
|
/* because a reversed order could create a deadlock */
|
|
/* situation. */
|
|
|
|
SetMode( ACQUISITION );
|
|
}
|
|
|
|
else
|
|
Set_TC_Error();
|
|
break;
|
|
|
|
case STOP_ACQUISITION:
|
|
if ( GetMode() == ACQUISITION ) {
|
|
SU_setting.SU_state = on_e;
|
|
SU_setting.expected_source_state = acquisition_e;
|
|
|
|
SU_setting.SU_number = SU_1;
|
|
Switch_SU_State ( &SU_setting );
|
|
/* Try to switch SU 1 to On state. */
|
|
|
|
SU_setting.SU_number = SU_2;
|
|
Switch_SU_State ( &SU_setting );
|
|
/* Try to switch SU 2 to On state. */
|
|
|
|
SU_setting.SU_number = SU_3;
|
|
Switch_SU_State ( &SU_setting );
|
|
/* Try to switch SU 3 to On state. */
|
|
|
|
SU_setting.SU_number = SU_4;
|
|
Switch_SU_State ( &SU_setting );
|
|
/* Try to switch SU 4 to On state. */
|
|
|
|
SetMode( STAND_BY );
|
|
}
|
|
|
|
else
|
|
Set_TC_Error();
|
|
break;
|
|
|
|
default:
|
|
UpdateTarget( command );
|
|
}
|
|
}
|
|
|
|
|
|
static EXTERNAL incoming_mail_t TC_mail;
|
|
/* Holds parameters for the mail waiting function. */
|
|
/* Must be in xdata memory because parameter of subrounite is pointer */
|
|
/* to xdata area. */
|
|
|
|
static EXTERNAL telecommand_t received_command;
|
|
/* Telecommand read form the mailbox is stored to TC_word component. */
|
|
/* Must be in external memory because parameters of subroutines (pointers */
|
|
/* to xdata area). */
|
|
|
|
|
|
void _Pragma( "entrypoint" ) InitTelecommandTask ( void )
|
|
|
|
/* Purpose : Initialize the global state of Telecommand Execution */
|
|
/* Interface : inputs - none */
|
|
/* outputs - TC state */
|
|
/* subroutines - DisableInterrupt */
|
|
/* EnableInterrupt */
|
|
/* Preconditions : none */
|
|
/* Postconditions : TelecommandExecutionTask is operational. */
|
|
/* Algorithm : - initialize task variables. */
|
|
|
|
{
|
|
InitTC_LookUp();
|
|
|
|
TC_state = TC_handling_e;
|
|
|
|
TC_mail.mailbox_number = TCTM_MAILBOX;
|
|
TC_mail.message = &( received_command.TC_word );
|
|
/* Parameters for mail waiting function. */
|
|
/* Time-out set separately. */
|
|
|
|
previous_TC.TC_word = 0;
|
|
previous_TC.TC_address = UNUSED_TC_ADDRESS;
|
|
previous_TC.TC_code = 0;
|
|
|
|
DisableInterrupt( TM_ISR_SOURCE );
|
|
EnableInterrupt( TC_ISR_SOURCE );
|
|
}
|
|
|
|
|
|
void _Pragma( "entrypoint" ) HandleTelecommand ( void )
|
|
|
|
/* Purpose : Waits for and handles one Telecommand from the TC ISR */
|
|
/* Interface : inputs - Telecommand Execution task mailbox */
|
|
/* TC state */
|
|
/* outputs - TC state */
|
|
/* subroutines - ReadMemory */
|
|
/* WriteMemory */
|
|
/* ExecuteCommand */
|
|
/* Preconditions : none */
|
|
/* Postconditions : one message removed from the TC mailbox */
|
|
/* Algorithm : - wait for mail to Telecommand Execution task mailbox */
|
|
/* - if mail is "TM_READY" and TC state is either */
|
|
/* "SC_TM_e" or "memory_dump_e". */
|
|
/* - if TC state is "SC_TM_e" */
|
|
/* - call ClearEvents function */
|
|
/* - set TC state to TC handling */
|
|
/* - else switch TC state */
|
|
/* - case ReadMemory_e : Check received TC's address */
|
|
/* - case WriteMemory_e : call WriteMemory function */
|
|
/* - case MemoryPatch_e : call MemoryPatch function */
|
|
/* - case TC_Handling : call ExecuteCommand */
|
|
/* NOTE: case register_TM_e is left out because */
|
|
/* operation of SEND_STATUS_REGISTER TC does not */
|
|
/* require any functionalites of this task. */
|
|
|
|
{
|
|
TC_mail.timeout = TC_timeout;
|
|
|
|
WaitMail( &TC_mail );
|
|
|
|
TC_timeout = 0;
|
|
/* Default value */
|
|
|
|
if ( TC_mail.execution_result == TIMEOUT_OCCURRED ) {
|
|
previous_TC.TC_word = 0;
|
|
previous_TC.TC_address = UNUSED_TC_ADDRESS;
|
|
previous_TC.TC_code = 0;
|
|
/* Forget previous telecommand. */
|
|
|
|
if ( TC_state != TC_handling_e ) {
|
|
/* Memory R/W time-out. */
|
|
Set_TC_Error();
|
|
}
|
|
|
|
TC_state = TC_handling_e;
|
|
}
|
|
|
|
else
|
|
if ( TC_mail.execution_result == MSG_RECEIVED ) {
|
|
received_command.TC_address = TC_ADDRESS ( received_command.TC_word );
|
|
received_command.TC_code = TC_CODE ( received_command.TC_word );
|
|
|
|
if ( ( ( TC_state == SC_TM_e ) || ( TC_state == memory_dump_e ) ) &&
|
|
( received_command.TC_word == TM_READY ) )
|
|
|
|
/* Note that in order to this condition to be sufficient, only */
|
|
/* TM interrupt service should be allowed to send mail to this */
|
|
/* task in the TC states mentioned. */
|
|
|
|
{
|
|
DisableInterrupt( TM_ISR_SOURCE );
|
|
|
|
if ( TC_state == SC_TM_e )
|
|
ClearEvents();
|
|
|
|
TC_state = TC_handling_e;
|
|
} else {
|
|
switch ( TC_state ) {
|
|
|
|
case read_memory_e:
|
|
|
|
if ( received_command.TC_address != READ_DATA_MEMORY_LSB ) {
|
|
Set_TC_Error();
|
|
TC_state = TC_handling_e;
|
|
}
|
|
|
|
break;
|
|
|
|
case write_memory_e:
|
|
WriteMemory ( &received_command );
|
|
break;
|
|
|
|
case memory_patch_e:
|
|
MemoryPatch ( &received_command );
|
|
break;
|
|
|
|
case TC_handling_e:
|
|
ExecuteCommand ( &received_command );
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
STRUCT_ASSIGN ( previous_TC, received_command, telecommand_t );
|
|
}
|
|
|
|
else {
|
|
/* Nothing is done if WaitMail returns an error message. */
|
|
}
|
|
}
|
|
|
|
|
|
void TelecommandExecutionTask( void ) TASK( TC_TM_INTERFACE_TASK )
|
|
PRIORITY( TC_TM_INTERFACE_PR )
|
|
/* Purpose : Implements the highest level of Telecommand Execution */
|
|
/* task */
|
|
/* Interface : inputs - Telecommand Execution task mailbox */
|
|
/* TC state */
|
|
/* outputs - TC state */
|
|
/* subroutines - InitTelecommandTask */
|
|
/* HandleTeleommand */
|
|
/* Preconditions : none */
|
|
/* Postconditions : This function does not return. */
|
|
/* Algorithm : - InitTelecommandTask */
|
|
/* - loop forever: */
|
|
/* - HandleTelecommand */
|
|
|
|
{
|
|
InitTelecommandTask ();
|
|
|
|
_Pragma( "loopbound min 0 max 0" )
|
|
while ( 1 )
|
|
HandleTelecommand ();
|
|
}
|
|
|
|
|
|
void Set_TC_Error( void )
|
|
/* Purpose : This function will be called always when TC_ERROR bit in */
|
|
/* the ErrorStatus register is set. */
|
|
/* Interface : inputs - Error_status register */
|
|
/* outputs - Error_status register */
|
|
/* subroutines - none */
|
|
/* Preconditions : none */
|
|
/* Postconditions : none */
|
|
/* Algorithm : - Disable interrupts */
|
|
/* - Write to Error Status register */
|
|
/* - Enable interrupts */
|
|
{
|
|
DISABLE_INTERRUPT_MASTER;
|
|
|
|
telemetry_data.error_status |= TC_ERROR;
|
|
|
|
ENABLE_INTERRUPT_MASTER;
|
|
}
|
|
|
|
/*Assign pointers to tasks*/
|
|
void ( * EXTERNAL TC_task )( void ) = TelecommandExecutionTask;
|