diff --git a/.hgsubstate b/.hgsubstate --- a/.hgsubstate +++ b/.hgsubstate @@ -1,2 +1,2 @@ 3081d1f9bb20b2b64a192585337a292a9804e0c5 LFR_basic-parameters -4ffa7549495b4d1e5ddbda520569468a5e3b8779 header/lfr_common_headers +ad7698268954c5d3d203a3b3ad09fcdf2d536472 header/lfr_common_headers diff --git a/header/GscMemoryLPP.hpp b/header/GscMemoryLPP.hpp --- a/header/GscMemoryLPP.hpp +++ b/header/GscMemoryLPP.hpp @@ -13,6 +13,8 @@ #define VENDORID_GAISLER 0x01 // CCR +#define POS_FT 19 +// #define POS_ITE 12 #define COUNTER_FIELD_ITE 0x00003000 // 0000 0000 0000 0000 0011 0000 0000 0000 #define COUNTER_MASK_ITE 0xffffcfff // 1111 1111 1111 1111 1100 1111 1111 1111 @@ -28,10 +30,16 @@ #define COUNTER_MASK_DDE 0xffffff3f // 1111 1111 1111 1111 1111 1111 0011 1111 // ASR16 +#define POS_FPFTID 30 #define POS_FPRF 27 +#define POS_FDI 16 // FP RF protection enable/disable +#define POS_IUFTID 14 +#define POS_IURF 11 +#define POS_IDI 0 // IU RF protection enable/disable + #define COUNTER_FIELD_FPRF 0x38000000 // 0011 1000 0000 0000 0000 0000 0000 0000 #define COUNTER_MASK_FPRF 0xc7ffffff // 1100 0111 1111 1111 1111 1111 1111 1111 -#define POS_IURF 11 + #define COUNTER_FIELD_IURF 0x00003800 // 0000 0000 0000 0000 0011 1000 0000 0000 #define COUNTER_MASK_IURF 0xffffc7ff // 1111 1111 1111 1111 1100 0111 1111 1111 @@ -92,32 +100,6 @@ static void CCR_enableDataCache() CCR_setValue(cacheControlRegister); } -static void CCR_faultTolerantScheme() -{ - // [20:19] FT scheme (FT) - “00” = no FT, “01” = 4-bit checking implemented - unsigned int cacheControlRegister; - unsigned int *plugAndPlayRegister; - unsigned int vendorId; - unsigned int deviceId; - - plugAndPlayRegister = (unsigned int*) REGS_ADDR_PLUGANDPLAY; - vendorId = ( (*plugAndPlayRegister) & 0xff000000 ) >> 24; - deviceId = ( (*plugAndPlayRegister) & 0x00fff000 ) >> 12; - - if( (vendorId == VENDORID_GAISLER) & (deviceId ==DEVICEID_LEON3FT) ) - { - PRINTF("in faultTolerantScheme *** Leon3FT detected, configure the CCR FT bits\n"); - cacheControlRegister = CCR_getValue(); - cacheControlRegister = (cacheControlRegister | 0xc); - CCR_setValue(cacheControlRegister); - } - else - { - PRINTF("in faultTolerantScheme *** not a Leon3FT, no need to configure the CCR FT bits\n"); - PRINTF2(" *** vendorID = 0x%x, deviceId = 0x%x\n", vendorId, deviceId); - } -} - static void CCR_enableInstructionBurstFetch() { // [16] Instruction burst fetch (IB). This bit enables burst fill during instruction fetch. @@ -128,7 +110,7 @@ static void CCR_enableInstructionBurstFe CCR_setValue(cacheControlRegister); } -static void CCR_getInstructionAndDataErrorCounters( unsigned int* instructionErrorCounter, unsigned int* dataErrorCounter ) +void CCR_getInstructionAndDataErrorCounters( unsigned int* instructionErrorCounter, unsigned int* dataErrorCounter ) { // [13:12] Instruction Tag Errors (ITE) - Number of detected parity errors in the instruction tag cache. // Only available if fault-tolerance is enabled (FT field in this register is non-zero). @@ -163,7 +145,12 @@ static void CCR_getInstructionAndDataErr //******************************************* // ASR16 Register protection control register -static void ASR16_get_FPRF_IURF_ErrorCounters( unsigned int* fprfErrorCounter, unsigned int* iurfErrorCounter) +static void ASR16_resetRegisterProtectionControlRegister() +{ + *asr16Ptr = 0x00; +} + +void ASR16_get_FPRF_IURF_ErrorCounters( unsigned int* fprfErrorCounter, unsigned int* iurfErrorCounter) { /** This function is used to retrieve the integer unit register file error counter and the floating point unit * register file error counter @@ -189,4 +176,46 @@ static void ASR16_get_FPRF_IURF_ErrorCou *asr16Ptr = asr16; } +static void faultTolerantScheme() +{ + // [20:19] FT scheme (FT) - “00” = no FT, “01” = 4-bit checking implemented + unsigned int cacheControlRegister; + unsigned int *plugAndPlayRegister; + unsigned int vendorId; + unsigned int deviceId; + + plugAndPlayRegister = (unsigned int*) REGS_ADDR_PLUGANDPLAY; + vendorId = ( (*plugAndPlayRegister) & 0xff000000 ) >> 24; + deviceId = ( (*plugAndPlayRegister) & 0x00fff000 ) >> 12; + + cacheControlRegister = CCR_getValue(); + + if( (vendorId == VENDORID_GAISLER) & (deviceId ==DEVICEID_LEON3FT) ) + { + PRINTF("in faultTolerantScheme *** Leon3FT detected\n"); + PRINTF2(" *** vendorID = 0x%x, deviceId = 0x%x\n", vendorId, deviceId); + PRINTF1("ASR16 IU RF protection, bit 0 (IDI) is: 0x%x (0 => protection enabled)\n", + (*asr16Ptr >> POS_IDI) & 1); + PRINTF1("ASR16 FP RF protection, bit 16 (FDI) is: 0x%x (0 => protection enabled)\n", + (*asr16Ptr >> POS_FDI) & 1); + PRINTF1("ASR16 IU FT ID bits [15:14] is: 0x%x (2 => 8-bit parity without restart)\n", + (*asr16Ptr >> POS_IUFTID) & 0x3); + PRINTF1("ASR16 FP FT ID bits [31:30] is: 0x%x (1 => 4-bit parity with restart)\n", + (*asr16Ptr >> POS_FPFTID) & 0x03); + PRINTF1("CCR FT bits [20:19] are: 0x%x (1 => 4-bit parity with restart)\n", + (cacheControlRegister >> POS_FT) & 0x3 ); + + // CCR The FFT bits are just read, the FT scheme is set to “01” = 4-bit checking implemented by default + + // ASR16 Ancillary State Register configuration (Register protection control register) + // IU RF protection is set by default, bit 0 IDI = 0 + // FP RF protection is set by default, bit 16 FDI = 0 + } + else + { + PRINTF("in faultTolerantScheme *** not a Leon3FT not detected\n"); + PRINTF2(" *** vendorID = 0x%x, deviceId = 0x%x\n", vendorId, deviceId); + } +} + #endif /* GSCMEMORY_HPP_ */ diff --git a/header/fsw_misc.h b/header/fsw_misc.h --- a/header/fsw_misc.h +++ b/header/fsw_misc.h @@ -10,6 +10,7 @@ #include "fsw_spacewire.h" #include "lfr_cpu_usage_report.h" + enum lfr_reset_cause_t{ UNKNOWN_CAUSE, POWER_ON, @@ -20,6 +21,8 @@ enum lfr_reset_cause_t{ }; extern gptimer_regs_t *gptimer_regs; +extern void ASR16_get_FPRF_IURF_ErrorCounters( unsigned int*, unsigned int* ); +extern void CCR_getInstructionAndDataErrorCounters( unsigned int*, unsigned int* ); #define LFR_RESET_CAUSE_UNKNOWN_CAUSE 0 diff --git a/header/processing/fsw_processing.h b/header/processing/fsw_processing.h --- a/header/processing/fsw_processing.h +++ b/header/processing/fsw_processing.h @@ -82,6 +82,8 @@ typedef struct asm_msg unsigned int fineTimeSBM; } asm_msg; +extern unsigned char thisIsAnASMRestart; + extern volatile int sm_f0[ ]; extern volatile int sm_f1[ ]; extern volatile int sm_f2[ ]; diff --git a/src/fsw_globals.c b/src/fsw_globals.c --- a/src/fsw_globals.c +++ b/src/fsw_globals.c @@ -32,6 +32,7 @@ int fdSPW = 0; int fdUART = 0; unsigned char lfrCurrentMode; unsigned char pa_bia_status_info; +unsigned char thisIsAnASMRestart = 0; // WAVEFORMS GLOBAL VARIABLES // 2048 * 3 * 4 + 2 * 4 = 24576 + 8 bytes = 24584 // 97 * 256 = 24832 => delta = 248 bytes = 62 words diff --git a/src/fsw_init.c b/src/fsw_init.c --- a/src/fsw_init.c +++ b/src/fsw_init.c @@ -81,19 +81,22 @@ void initCache() unsigned int cacheControlRegister; + CCR_resetCacheControlRegister(); + ASR16_resetRegisterProtectionControlRegister(); + cacheControlRegister = CCR_getValue(); - PRINTF1("(0) cacheControlRegister = %x\n", cacheControlRegister); - - CCR_resetCacheControlRegister(); + PRINTF1("(0) CCR - Cache Control Register = %x\n", cacheControlRegister); + PRINTF1("(0) ASR16 = %x\n", *asr16Ptr); CCR_enableInstructionCache(); // ICS bits CCR_enableDataCache(); // DCS bits CCR_enableInstructionBurstFetch(); // IB bit + faultTolerantScheme(); + cacheControlRegister = CCR_getValue(); - PRINTF1("(1) cacheControlRegister = %x\n", cacheControlRegister); - - CCR_faultTolerantScheme(); + PRINTF1("(1) CCR - Cache Control Register = %x\n", cacheControlRegister); + PRINTF1("(1) ASR16 Register protection control register = %x\n", *asr16Ptr); PRINTF("\n"); } @@ -198,8 +201,6 @@ rtems_task Init( rtems_task_argument ign // ************************** // - grspw_timecode_callback = &timecode_irq_handler; - status_spw = spacewire_open_link(); // (1) open the link if ( status_spw != RTEMS_SUCCESSFUL ) { @@ -268,8 +269,11 @@ rtems_task Init( rtems_task_argument ign set_hk_lfr_sc_potential_flag( true ); - // start the timer used for the detection of missing parameters (started also by the timecode_irq_handler ISR) - status = rtems_timer_fire_after( timecode_timer_id, TIMECODE_TIMER_TIMEOUT, timecode_timer_routine, NULL ); + // start the timer to detect a missing spacewire timecode + // the timeout is larger because the spw IP needs to receive several valid timecodes before generating a tickout + // if a tickout is generated, the timer is restarted + status = rtems_timer_fire_after( timecode_timer_id, TIMECODE_TIMER_TIMEOUT_INIT, timecode_timer_routine, NULL ); + grspw_timecode_callback = &timecode_irq_handler; status = rtems_task_delete(RTEMS_SELF); diff --git a/src/fsw_misc.c b/src/fsw_misc.c --- a/src/fsw_misc.c +++ b/src/fsw_misc.c @@ -232,21 +232,21 @@ rtems_task hous_task(rtems_task_argument PRINTF1("in HOUS *** ERR get_message_queue_id_send %d\n", status) } - BOOT_PRINTF("in HOUS ***\n") + BOOT_PRINTF("in HOUS ***\n"); if (rtems_rate_monotonic_ident( name_hk_rate_monotonic, &HK_id) != RTEMS_SUCCESSFUL) { status = rtems_rate_monotonic_create( name_hk_rate_monotonic, &HK_id ); if( status != RTEMS_SUCCESSFUL ) { - PRINTF1( "rtems_rate_monotonic_create failed with status of %d\n", status ) + PRINTF1( "rtems_rate_monotonic_create failed with status of %d\n", status ); } } status = rtems_rate_monotonic_cancel(HK_id); if( status != RTEMS_SUCCESSFUL ) { - PRINTF1( "ERR *** in HOUS *** rtems_rate_monotonic_cancel(HK_id) ***code: %d\n", status ) + PRINTF1( "ERR *** in HOUS *** rtems_rate_monotonic_cancel(HK_id) ***code: %d\n", status ); } else { - DEBUG_PRINTF("OK *** in HOUS *** rtems_rate_monotonic_cancel(HK_id)\n") + DEBUG_PRINTF("OK *** in HOUS *** rtems_rate_monotonic_cancel(HK_id)\n"); } // startup phase @@ -339,7 +339,7 @@ rtems_task dumb_task( rtems_task_argumen unsigned int fine_time = 0; rtems_event_set event_out; - char *DumbMessages[14] = {"in DUMB *** default", // RTEMS_EVENT_0 + char *DumbMessages[15] = {"in DUMB *** default", // RTEMS_EVENT_0 "in DUMB *** timecode_irq_handler", // RTEMS_EVENT_1 "in DUMB *** f3 buffer changed", // RTEMS_EVENT_2 "in DUMB *** in SMIQ *** Error sending event to AVF0", // RTEMS_EVENT_3 @@ -352,7 +352,8 @@ rtems_task dumb_task( rtems_task_argumen "VHDL ERR *** waveform picker", // RTEMS_EVENT_10 "VHDL ERR *** unexpected ready matrix values", // RTEMS_EVENT_11 "WATCHDOG timer", // RTEMS_EVENT_12 - "TIMECODE timer" // RTEMS_EVENT_13 + "TIMECODE timer", // RTEMS_EVENT_13 + "TIMECODE ISR" // RTEMS_EVENT_14 }; BOOT_PRINTF("in DUMB *** \n") @@ -360,7 +361,8 @@ rtems_task dumb_task( rtems_task_argumen while(1){ rtems_event_receive(RTEMS_EVENT_0 | RTEMS_EVENT_1 | RTEMS_EVENT_2 | RTEMS_EVENT_3 | RTEMS_EVENT_4 | RTEMS_EVENT_5 | RTEMS_EVENT_6 | RTEMS_EVENT_7 - | RTEMS_EVENT_8 | RTEMS_EVENT_9 | RTEMS_EVENT_12 | RTEMS_EVENT_13, + | RTEMS_EVENT_8 | RTEMS_EVENT_9 | RTEMS_EVENT_12 | RTEMS_EVENT_13 + | RTEMS_EVENT_14, RTEMS_WAIT | RTEMS_EVENT_ANY, RTEMS_NO_TIMEOUT, &event_out); // wait for an RTEMS_EVENT intEventOut = (unsigned int) event_out; for ( i=0; i<32; i++) @@ -377,6 +379,10 @@ rtems_task dumb_task( rtems_task_argumen { PRINTF1("%s\n", DumbMessages[13]) } + if (i==14) + { + PRINTF1("%s\n", DumbMessages[1]) + } } } } @@ -735,3 +741,43 @@ void set_hk_lfr_time_not_synchro() } } + +void set_hk_lfr_ahb_correctable() +{ + /** This function builds the error counter hk_lfr_ahb_correctable using the statistics provided + * by the Cache Control Register (ASI 2, offset 0) and in the Register Protection Control Register (ASR16) on the + * detected errors in the cache, in the integer unit and in the floating point unit. + * + * @param void + * + * @return void + * + * All errors are summed to set the value of the hk_lfr_ahb_correctable counter. + * + */ + + unsigned int ahb_correctable; + unsigned int instructionErrorCounter; + unsigned int dataErrorCounter; + unsigned int fprfErrorCounter; + unsigned int iurfErrorCounter; + + CCR_getInstructionAndDataErrorCounters( &instructionErrorCounter, &dataErrorCounter); + ASR16_get_FPRF_IURF_ErrorCounters( &fprfErrorCounter, &iurfErrorCounter); + + ahb_correctable = instructionErrorCounter + + dataErrorCounter + + fprfErrorCounter + + iurfErrorCounter + + housekeeping_packet.hk_lfr_ahb_correctable; + + if (ahb_correctable > 255) + { + housekeeping_packet.hk_lfr_ahb_correctable = 255; + } + else + { + housekeeping_packet.hk_lfr_ahb_correctable = ahb_correctable; + } + +} diff --git a/src/fsw_spacewire.c b/src/fsw_spacewire.c --- a/src/fsw_spacewire.c +++ b/src/fsw_spacewire.c @@ -680,30 +680,41 @@ void increase_unsigned_char_counter( uns rtems_timer_service_routine timecode_timer_routine( rtems_id timer_id, void *user_data ) { + static unsigned char initStep = 1; unsigned char currentTimecodeCtr; currentTimecodeCtr = (unsigned char) (grspwPtr[0] & TIMECODE_MASK); - if (currentTimecodeCtr == previousTimecodeCtr) + if (initStep == 1) { - //************************ - // HK_LFR_TIMECODE_MISSING - // the timecode value has not changed, no valid timecode has been received, the timecode is MISSING - increase_unsigned_char_counter( &housekeeping_packet.hk_lfr_timecode_missing ); - } - else if (currentTimecodeCtr == (previousTimecodeCtr+1)) - { - // the timecode value has changed and the value is valid, this is unexpected because - // the timer should not have fired, the timecode_irq_handler should have been raised + if (currentTimecodeCtr == previousTimecodeCtr) + { + //************************ + // HK_LFR_TIMECODE_MISSING + // the timecode value has not changed, no valid timecode has been received, the timecode is MISSING + increase_unsigned_char_counter( &housekeeping_packet.hk_lfr_timecode_missing ); + } + else if (currentTimecodeCtr == (previousTimecodeCtr+1)) + { + // the timecode value has changed and the value is valid, this is unexpected because + // the timer should not have fired, the timecode_irq_handler should have been raised + } + else + { + //************************ + // HK_LFR_TIMECODE_INVALID + // the timecode value has changed and the value is not valid, no tickout has been generated + // this is why the timer has fired + increase_unsigned_char_counter( &housekeeping_packet.hk_lfr_timecode_invalid ); + } } else { + initStep = 1; //************************ - // HK_LFR_TIMECODE_INVALID - // the timecode value has changed and the value is not valid, no tickout has been generated - // this is why the timer has fired - increase_unsigned_char_counter( &housekeeping_packet.hk_lfr_timecode_invalid ); + // HK_LFR_TIMECODE_MISSING + increase_unsigned_char_counter( &housekeeping_packet.hk_lfr_timecode_missing ); } rtems_event_send( Task_id[TASKID_DUMB], RTEMS_EVENT_13 ); @@ -824,6 +835,10 @@ void timecode_irq_handler( void *pDev, v // launch the timecode timer to detect missing or invalid timecodes previousTimecodeCtr = incomingTimecode; // update the previousTimecodeCtr value status = rtems_timer_fire_after( timecode_timer_id, TIMECODE_TIMER_TIMEOUT, timecode_timer_routine, NULL ); + if (status != RTEMS_SUCCESSFUL) + { + rtems_event_send( Task_id[TASKID_DUMB], RTEMS_EVENT_14 ); + } } void init_header_cwf( Header_TM_LFR_SCIENCE_CWF_t *header ) diff --git a/src/processing/avf0_prc0.c b/src/processing/avf0_prc0.c --- a/src/processing/avf0_prc0.c +++ b/src/processing/avf0_prc0.c @@ -41,7 +41,7 @@ rtems_task avf0_task( rtems_task_argumen rtems_event_set event_out; rtems_status_code status; rtems_id queue_id_prc0; - asm_msg msgForMATR; + asm_msg msgForPRC; ring_node *nodeForAveraging; ring_node *ring_node_tab[8]; ring_node_asm *current_ring_node_asm_burst_sbm_f0; @@ -78,9 +78,9 @@ rtems_task avf0_task( rtems_task_argumen //**************************************** // initialize the mesage for the MATR task - msgForMATR.norm = current_ring_node_asm_norm_f0; - msgForMATR.burst_sbm = current_ring_node_asm_burst_sbm_f0; - msgForMATR.event = 0x00; // this composite event will be sent to the PRC0 task + msgForPRC.norm = current_ring_node_asm_norm_f0; + msgForPRC.burst_sbm = current_ring_node_asm_burst_sbm_f0; + msgForPRC.event = 0x00; // this composite event will be sent to the PRC0 task // //**************************************** @@ -98,7 +98,7 @@ rtems_task avf0_task( rtems_task_argumen current_ring_node_asm_burst_sbm_f0->matrix, ring_node_tab, nb_norm_bp1, nb_sbm_bp1, - &msgForMATR ); + &msgForPRC ); // update nb_average nb_norm_bp1 = nb_norm_bp1 + NB_SM_BEFORE_AVF0; @@ -114,11 +114,11 @@ rtems_task avf0_task( rtems_task_argumen current_ring_node_asm_burst_sbm_f0 = current_ring_node_asm_burst_sbm_f0->next; if ( lfrCurrentMode == LFR_MODE_BURST ) { - msgForMATR.event = msgForMATR.event | RTEMS_EVENT_BURST_BP1_F0; + msgForPRC.event = msgForPRC.event | RTEMS_EVENT_BURST_BP1_F0; } else if ( (lfrCurrentMode == LFR_MODE_SBM1) || (lfrCurrentMode == LFR_MODE_SBM2) ) { - msgForMATR.event = msgForMATR.event | RTEMS_EVENT_SBM_BP1_F0; + msgForPRC.event = msgForPRC.event | RTEMS_EVENT_SBM_BP1_F0; } } @@ -127,11 +127,11 @@ rtems_task avf0_task( rtems_task_argumen nb_sbm_bp2 = 0; if ( lfrCurrentMode == LFR_MODE_BURST ) { - msgForMATR.event = msgForMATR.event | RTEMS_EVENT_BURST_BP2_F0; + msgForPRC.event = msgForPRC.event | RTEMS_EVENT_BURST_BP2_F0; } else if ( (lfrCurrentMode == LFR_MODE_SBM1) || (lfrCurrentMode == LFR_MODE_SBM2) ) { - msgForMATR.event = msgForMATR.event | RTEMS_EVENT_SBM_BP2_F0; + msgForPRC.event = msgForPRC.event | RTEMS_EVENT_SBM_BP2_F0; } } @@ -143,7 +143,7 @@ rtems_task avf0_task( rtems_task_argumen if ( (lfrCurrentMode == LFR_MODE_NORMAL) || (lfrCurrentMode == LFR_MODE_SBM1) || (lfrCurrentMode == LFR_MODE_SBM2) ) { - msgForMATR.event = msgForMATR.event | RTEMS_EVENT_NORM_BP1_F0; + msgForPRC.event = msgForPRC.event | RTEMS_EVENT_NORM_BP1_F0; } } @@ -153,7 +153,7 @@ rtems_task avf0_task( rtems_task_argumen if ( (lfrCurrentMode == LFR_MODE_NORMAL) || (lfrCurrentMode == LFR_MODE_SBM1) || (lfrCurrentMode == LFR_MODE_SBM2) ) { - msgForMATR.event = msgForMATR.event | RTEMS_EVENT_NORM_BP2_F0; + msgForPRC.event = msgForPRC.event | RTEMS_EVENT_NORM_BP2_F0; } } @@ -163,19 +163,19 @@ rtems_task avf0_task( rtems_task_argumen if ( (lfrCurrentMode == LFR_MODE_NORMAL) || (lfrCurrentMode == LFR_MODE_SBM1) || (lfrCurrentMode == LFR_MODE_SBM2) ) { - msgForMATR.event = msgForMATR.event | RTEMS_EVENT_NORM_ASM_F0; + msgForPRC.event = msgForPRC.event | RTEMS_EVENT_NORM_ASM_F0; } } //************************* - // send the message to MATR - if (msgForMATR.event != 0x00) + // send the message to PRC + if (msgForPRC.event != 0x00) { - status = rtems_message_queue_send( queue_id_prc0, (char *) &msgForMATR, MSG_QUEUE_SIZE_PRC0); + status = rtems_message_queue_send( queue_id_prc0, (char *) &msgForPRC, MSG_QUEUE_SIZE_PRC0); } if (status != RTEMS_SUCCESSFUL) { - PRINTF1("in AVF0 *** Error sending message to MATR, code %d\n", status) + PRINTF1("in AVF0 *** Error sending message to PRC, code %d\n", status) } } } diff --git a/src/processing/avf1_prc1.c b/src/processing/avf1_prc1.c --- a/src/processing/avf1_prc1.c +++ b/src/processing/avf1_prc1.c @@ -42,7 +42,7 @@ rtems_task avf1_task( rtems_task_argumen rtems_event_set event_out; rtems_status_code status; rtems_id queue_id_prc1; - asm_msg msgForMATR; + asm_msg msgForPRC; ring_node *nodeForAveraging; ring_node *ring_node_tab[NB_SM_BEFORE_AVF0]; ring_node_asm *current_ring_node_asm_burst_sbm_f1; @@ -79,9 +79,9 @@ rtems_task avf1_task( rtems_task_argumen //**************************************** // initialize the mesage for the MATR task - msgForMATR.norm = current_ring_node_asm_norm_f1; - msgForMATR.burst_sbm = current_ring_node_asm_burst_sbm_f1; - msgForMATR.event = 0x00; // this composite event will be sent to the PRC1 task + msgForPRC.norm = current_ring_node_asm_norm_f1; + msgForPRC.burst_sbm = current_ring_node_asm_burst_sbm_f1; + msgForPRC.event = 0x00; // this composite event will be sent to the PRC1 task // //**************************************** @@ -99,7 +99,7 @@ rtems_task avf1_task( rtems_task_argumen current_ring_node_asm_burst_sbm_f1->matrix, ring_node_tab, nb_norm_bp1, nb_sbm_bp1, - &msgForMATR ); + &msgForPRC ); // update nb_average nb_norm_bp1 = nb_norm_bp1 + NB_SM_BEFORE_AVF1; @@ -115,11 +115,11 @@ rtems_task avf1_task( rtems_task_argumen current_ring_node_asm_burst_sbm_f1 = current_ring_node_asm_burst_sbm_f1->next; if ( lfrCurrentMode == LFR_MODE_BURST ) { - msgForMATR.event = msgForMATR.event | RTEMS_EVENT_BURST_BP1_F1; + msgForPRC.event = msgForPRC.event | RTEMS_EVENT_BURST_BP1_F1; } else if ( lfrCurrentMode == LFR_MODE_SBM2 ) { - msgForMATR.event = msgForMATR.event | RTEMS_EVENT_SBM_BP1_F1; + msgForPRC.event = msgForPRC.event | RTEMS_EVENT_SBM_BP1_F1; } } @@ -128,11 +128,11 @@ rtems_task avf1_task( rtems_task_argumen nb_sbm_bp2 = 0; if ( lfrCurrentMode == LFR_MODE_BURST ) { - msgForMATR.event = msgForMATR.event | RTEMS_EVENT_BURST_BP2_F1; + msgForPRC.event = msgForPRC.event | RTEMS_EVENT_BURST_BP2_F1; } else if ( lfrCurrentMode == LFR_MODE_SBM2 ) { - msgForMATR.event = msgForMATR.event | RTEMS_EVENT_SBM_BP2_F1; + msgForPRC.event = msgForPRC.event | RTEMS_EVENT_SBM_BP2_F1; } } @@ -144,7 +144,7 @@ rtems_task avf1_task( rtems_task_argumen if ( (lfrCurrentMode == LFR_MODE_NORMAL) || (lfrCurrentMode == LFR_MODE_SBM1) || (lfrCurrentMode == LFR_MODE_SBM2) ) { - msgForMATR.event = msgForMATR.event | RTEMS_EVENT_NORM_BP1_F1; + msgForPRC.event = msgForPRC.event | RTEMS_EVENT_NORM_BP1_F1; } } @@ -154,7 +154,7 @@ rtems_task avf1_task( rtems_task_argumen if ( (lfrCurrentMode == LFR_MODE_NORMAL) || (lfrCurrentMode == LFR_MODE_SBM1) || (lfrCurrentMode == LFR_MODE_SBM2) ) { - msgForMATR.event = msgForMATR.event | RTEMS_EVENT_NORM_BP2_F1; + msgForPRC.event = msgForPRC.event | RTEMS_EVENT_NORM_BP2_F1; } } @@ -164,15 +164,15 @@ rtems_task avf1_task( rtems_task_argumen if ( (lfrCurrentMode == LFR_MODE_NORMAL) || (lfrCurrentMode == LFR_MODE_SBM1) || (lfrCurrentMode == LFR_MODE_SBM2) ) { - msgForMATR.event = msgForMATR.event | RTEMS_EVENT_NORM_ASM_F1; + msgForPRC.event = msgForPRC.event | RTEMS_EVENT_NORM_ASM_F1; } } //************************* - // send the message to MATR - if (msgForMATR.event != 0x00) + // send the message to PRC + if (msgForPRC.event != 0x00) { - status = rtems_message_queue_send( queue_id_prc1, (char *) &msgForMATR, MSG_QUEUE_SIZE_PRC1); + status = rtems_message_queue_send( queue_id_prc1, (char *) &msgForPRC, MSG_QUEUE_SIZE_PRC1); } if (status != RTEMS_SUCCESSFUL) { diff --git a/src/processing/avf2_prc2.c b/src/processing/avf2_prc2.c --- a/src/processing/avf2_prc2.c +++ b/src/processing/avf2_prc2.c @@ -38,7 +38,7 @@ rtems_task avf2_task( rtems_task_argumen rtems_event_set event_out; rtems_status_code status; rtems_id queue_id_prc2; - asm_msg msgForMATR; + asm_msg msgForPRC; ring_node *nodeForAveraging; ring_node_asm *current_ring_node_asm_norm_f2; @@ -67,9 +67,9 @@ rtems_task avf2_task( rtems_task_argumen //**************************************** // initialize the mesage for the MATR task - msgForMATR.norm = current_ring_node_asm_norm_f2; - msgForMATR.burst_sbm = NULL; - msgForMATR.event = 0x00; // this composite event will be sent to the PRC2 task + msgForPRC.norm = current_ring_node_asm_norm_f2; + msgForPRC.burst_sbm = NULL; + msgForPRC.event = 0x00; // this composite event will be sent to the PRC2 task // //**************************************** @@ -79,7 +79,7 @@ rtems_task avf2_task( rtems_task_argumen SM_average_f2( current_ring_node_asm_norm_f2->matrix, nodeForAveraging, nb_norm_bp1, - &msgForMATR ); + &msgForPRC ); // update nb_average nb_norm_bp1 = nb_norm_bp1 + NB_SM_BEFORE_AVF2; @@ -94,7 +94,7 @@ rtems_task avf2_task( rtems_task_argumen if ( (lfrCurrentMode == LFR_MODE_NORMAL) || (lfrCurrentMode == LFR_MODE_SBM1) || (lfrCurrentMode == LFR_MODE_SBM2) ) { - msgForMATR.event = msgForMATR.event | RTEMS_EVENT_NORM_BP1_F2; + msgForPRC.event = msgForPRC.event | RTEMS_EVENT_NORM_BP1_F2; } } @@ -104,7 +104,7 @@ rtems_task avf2_task( rtems_task_argumen if ( (lfrCurrentMode == LFR_MODE_NORMAL) || (lfrCurrentMode == LFR_MODE_SBM1) || (lfrCurrentMode == LFR_MODE_SBM2) ) { - msgForMATR.event = msgForMATR.event | RTEMS_EVENT_NORM_BP2_F2; + msgForPRC.event = msgForPRC.event | RTEMS_EVENT_NORM_BP2_F2; } } @@ -114,19 +114,19 @@ rtems_task avf2_task( rtems_task_argumen if ( (lfrCurrentMode == LFR_MODE_NORMAL) || (lfrCurrentMode == LFR_MODE_SBM1) || (lfrCurrentMode == LFR_MODE_SBM2) ) { - msgForMATR.event = msgForMATR.event | RTEMS_EVENT_NORM_ASM_F2; + msgForPRC.event = msgForPRC.event | RTEMS_EVENT_NORM_ASM_F2; } } //************************* - // send the message to MATR - if (msgForMATR.event != 0x00) + // send the message to PRC2 + if (msgForPRC.event != 0x00) { - status = rtems_message_queue_send( queue_id_prc2, (char *) &msgForMATR, MSG_QUEUE_SIZE_PRC2); + status = rtems_message_queue_send( queue_id_prc2, (char *) &msgForPRC, MSG_QUEUE_SIZE_PRC2); } if (status != RTEMS_SUCCESSFUL) { - PRINTF1("in AVF2 *** Error sending message to MATR, code %d\n", status) + PRINTF1("in AVF2 *** Error sending message to PRC2, code %d\n", status) } } } diff --git a/src/processing/fsw_processing.c b/src/processing/fsw_processing.c --- a/src/processing/fsw_processing.c +++ b/src/processing/fsw_processing.c @@ -16,6 +16,13 @@ unsigned int nb_sm_f0_aux_f1; unsigned int nb_sm_f1; unsigned int nb_sm_f0_aux_f2; +typedef enum restartState_t +{ + WAIT_FOR_F2, + WAIT_FOR_F1, + WAIT_FOR_F0 +} restartState; + //************************ // spectral matrices rings ring_node sm_ring_f0[ NB_RING_NODES_SM_F0 ]; @@ -118,7 +125,7 @@ void spectral_matrices_isr_f1( unsigned unsigned char status; ring_node *full_ring_node; - status = (statusReg & 0x0c) >> 2; // [1100] get the status_ready_matrix_f0_x bits + status = (statusReg & 0x0c) >> 2; // [1100] get the status_ready_matrix_f1_x bits switch(status) { @@ -175,7 +182,7 @@ void spectral_matrices_isr_f2( unsigned unsigned char status; rtems_status_code status_code; - status = (statusReg & 0x30) >> 4; // [0011 0000] get the status_ready_matrix_f0_x bits + status = (statusReg & 0x30) >> 4; // [0011 0000] get the status_ready_matrix_f2_x bits switch(status) { @@ -235,15 +242,48 @@ rtems_isr spectral_matrices_isr( rtems_v unsigned char statusReg; + static restartState state = WAIT_FOR_F2; + statusReg = spectral_matrix_regs->status; - spectral_matrices_isr_f0( statusReg ); + if (thisIsAnASMRestart == 0) + { // this is not a restart sequence, process incoming matrices normally + spectral_matrices_isr_f0( statusReg ); + + spectral_matrices_isr_f1( statusReg ); - spectral_matrices_isr_f1( statusReg ); - - spectral_matrices_isr_f2( statusReg ); + spectral_matrices_isr_f2( statusReg ); + } + else + { // a restart sequence has to be launched + switch (state) { + case WAIT_FOR_F2: + if ((statusReg & 0x30) != 0x00) // [0011 0000] check the status_ready_matrix_f2_x bits + { + state = WAIT_FOR_F1; + } + break; + case WAIT_FOR_F1: + if ((statusReg & 0x0c) != 0x00) // [0000 1100] check the status_ready_matrix_f1_x bits + { + state = WAIT_FOR_F0; + } + break; + case WAIT_FOR_F0: + if ((statusReg & 0x03) != 0x00) // [0000 0011] check the status_ready_matrix_f0_x bits + { + state = WAIT_FOR_F2; + thisIsAnASMRestart = 0; + } + break; + default: + break; + } + reset_sm_status(); + } spectral_matrix_isr_error_handler( statusReg ); + } //****************** @@ -403,7 +443,7 @@ void BP_send_s1_s2(char *data, rtems_id // SEND PACKET // before lastValidTransitionDate, the data are drops even if they are ready - // this guarantees that no SBM packets will be received before the requestion enter mode time + // this guarantees that no SBM packets will be received before the requested enter mode time if ( time_management_regs->coarse_time >= lastValidEnterModeTime) { status = rtems_message_queue_send( queue_id, data, nbBytesToSend); diff --git a/src/tc_handler.c b/src/tc_handler.c --- a/src/tc_handler.c +++ b/src/tc_handler.c @@ -228,11 +228,11 @@ int action_enter_mode(ccsdsTelecommandPa default: break; } - } - if (status != RTEMS_SUCCESSFUL) - { - status = LFR_EXE_ERROR; + if (status != RTEMS_SUCCESSFUL) + { + status = LFR_EXE_ERROR; + } } return status; @@ -507,6 +507,8 @@ int restart_asm_activities( unsigned cha status = stop_spectral_matrices(); + thisIsAnASMRestart = 1; + status = restart_asm_tasks( lfrRequestedMode ); launch_spectral_matrix(); @@ -530,7 +532,7 @@ int stop_spectral_matrices( void ) status = RTEMS_SUCCESSFUL; // (1) mask interruptions - LEON_Mask_interrupt( IRQ_SPECTRAL_MATRIX ); // clear spectral matrix interrupt + LEON_Mask_interrupt( IRQ_SPECTRAL_MATRIX ); // mask spectral matrix interrupt // (2) reset spectral matrices registers set_sm_irq_onNewMatrix( 0 ); // stop the spectral matrices