diff --git a/FSW-qt/Makefile b/FSW-qt/Makefile --- a/FSW-qt/Makefile +++ b/FSW-qt/Makefile @@ -1,6 +1,6 @@ ############################################################################# # Makefile for building: bin/fsw -# Generated by qmake (2.01a) (Qt 4.8.6) on: Tue Jul 15 15:57:23 2014 +# Generated by qmake (2.01a) (Qt 4.8.6) on: Thu Jul 17 15:49:45 2014 # Project: fsw-qt.pro # Template: app # Command: /usr/bin/qmake-qt4 -spec /usr/lib64/qt4/mkspecs/linux-g++ -o Makefile fsw-qt.pro @@ -10,7 +10,7 @@ CC = sparc-rtems-gcc CXX = sparc-rtems-g++ -DEFINES = -DSW_VERSION_N1=2 -DSW_VERSION_N2=0 -DSW_VERSION_N3=1 -DSW_VERSION_N4=0 -DPRINT_MESSAGES_ON_CONSOLE +DEFINES = -DSW_VERSION_N1=2 -DSW_VERSION_N2=0 -DSW_VERSION_N3=1 -DSW_VERSION_N4=1 -DPRINT_MESSAGES_ON_CONSOLE -DPRINT_TASK_STATISTICS -DFAST_SCHEDULER CFLAGS = -pipe -O3 -Wall $(DEFINES) CXXFLAGS = -pipe -O3 -Wall $(DEFINES) INCPATH = -I/usr/lib64/qt4/mkspecs/linux-g++ -I. -I../src -I../header -I../header/processing -I../src/LFR_basic-parameters @@ -57,7 +57,8 @@ SOURCES = ../src/wf_handler.c \ ../src/processing/avf1_prc1.c \ ../src/processing/avf2_prc2.c \ ../src/lfr_cpu_usage_report.c \ - ../src/LFR_basic-parameters/basic_parameters.c + ../src/LFR_basic-parameters/basic_parameters.c \ + ../src/fsw_spool.c OBJECTS = obj/wf_handler.o \ obj/tc_handler.o \ obj/fsw_misc.o \ @@ -72,7 +73,8 @@ OBJECTS = obj/wf_handler.o \ obj/avf1_prc1.o \ obj/avf2_prc2.o \ obj/lfr_cpu_usage_report.o \ - obj/basic_parameters.o + obj/basic_parameters.o \ + obj/fsw_spool.o DIST = /usr/lib64/qt4/mkspecs/common/unix.conf \ /usr/lib64/qt4/mkspecs/common/linux.conf \ /usr/lib64/qt4/mkspecs/common/gcc-base.conf \ @@ -263,6 +265,9 @@ obj/lfr_cpu_usage_report.o: ../src/lfr_c obj/basic_parameters.o: ../src/LFR_basic-parameters/basic_parameters.c $(CC) -c $(CFLAGS) $(INCPATH) -o obj/basic_parameters.o ../src/LFR_basic-parameters/basic_parameters.c +obj/fsw_spool.o: ../src/fsw_spool.c + $(CC) -c $(CFLAGS) $(INCPATH) -o obj/fsw_spool.o ../src/fsw_spool.c + ####### Install install: FORCE diff --git a/FSW-qt/bin/Makefile b/FSW-qt/bin/Makefile --- a/FSW-qt/bin/Makefile +++ b/FSW-qt/bin/Makefile @@ -1,10 +1,9 @@ SREC_PREFIX = RpwLfrApp -SREC_COUNTER_TEXT = 0003 -SREC_COUNTER_DATA = 0004 -SREC_FSW_REF = rev-1-0-0-7 +SREC_COUNTER = 0003 +SREC_FSW_REF = rev-2-0-1-0 SREC_SUFFIX = .srec -SREC_TEXT = $(SREC_PREFIX)_$(SREC_COUNTER_TEXT)_text_$(SREC_FSW_REF)$(SREC_SUFFIX) -SREC_DATA = $(SREC_PREFIX)_$(SREC_COUNTER_DATA)_data_$(SREC_FSW_REF)$(SREC_SUFFIX) +SREC_TEXT = $(SREC_PREFIX)_$(SREC_COUNTER)_text_$(SREC_FSW_REF)$(SREC_SUFFIX) +SREC_DATA = $(SREC_PREFIX)_$(SREC_COUNTER)_data_$(SREC_FSW_REF)$(SREC_SUFFIX) OBJCOPY = sparc-rtems-objcopy OBJCOPY_OPT = -g -v diff --git a/FSW-qt/fsw-qt.pro b/FSW-qt/fsw-qt.pro --- a/FSW-qt/fsw-qt.pro +++ b/FSW-qt/fsw-qt.pro @@ -1,7 +1,7 @@ TEMPLATE = app # CONFIG += console v8 sim # CONFIG options = verbose *** boot_messages *** debug_messages *** cpu_usage_report *** stack_report *** vhdl_dev *** debug_tch -CONFIG += console verbose +CONFIG += console verbose fast_scheduler cpu_usage_report CONFIG -= qt include(./sparc.pri) @@ -11,7 +11,7 @@ SWVERSION=-1-0 DEFINES += SW_VERSION_N1=2 # major DEFINES += SW_VERSION_N2=0 # minor DEFINES += SW_VERSION_N3=1 # patch -DEFINES += SW_VERSION_N4=0 # internal +DEFINES += SW_VERSION_N4=1 # internal contains( CONFIG, debug_tch ) { DEFINES += DEBUG_TCH @@ -41,6 +41,10 @@ contains( CONFIG, boot_messages ) { DEFINES += BOOT_MESSAGES } +contains( CONFIG, fast_scheduler ) { + DEFINES += FAST_SCHEDULER +} + #doxygen.target = doxygen #doxygen.commands = doxygen ../doc/Doxyfile #QMAKE_EXTRA_TARGETS += doxygen @@ -68,7 +72,8 @@ SOURCES += \ ../src/processing/avf1_prc1.c \ ../src/processing/avf2_prc2.c \ ../src/lfr_cpu_usage_report.c \ - ../src/LFR_basic-parameters/basic_parameters.c + ../src/LFR_basic-parameters/basic_parameters.c \ + ../src/fsw_spool.c HEADERS += \ ../header/wf_handler.h \ @@ -91,5 +96,6 @@ HEADERS += \ ../header/fsw_params_wf_handler.h \ ../header/lfr_cpu_usage_report.h \ ../src/LFR_basic-parameters/basic_parameters.h \ - ../src/LFR_basic-parameters/basic_parameters_params.h + ../src/LFR_basic-parameters/basic_parameters_params.h \ + ../header/fsw_spool.h diff --git a/FSW-qt/fsw-qt.pro.user b/FSW-qt/fsw-qt.pro.user --- a/FSW-qt/fsw-qt.pro.user +++ b/FSW-qt/fsw-qt.pro.user @@ -1,6 +1,6 @@ - + ProjectExplorer.Project.ActiveTarget @@ -29,9 +29,12 @@ false 4 false + 80 + true true 1 true + false 0 true 0 diff --git a/header/fsw_init.h b/header/fsw_init.h --- a/header/fsw_init.h +++ b/header/fsw_init.h @@ -15,9 +15,10 @@ #include "avf0_prc0.h" #include "avf1_prc1.h" #include "avf2_prc2.h" +#include "fsw_spool.h" -extern rtems_name Task_name[20]; /* array of task names */ -extern rtems_id Task_id[20]; /* array of task ids */ +extern rtems_name Task_name[]; /* array of task names */ +extern rtems_id Task_id[]; /* array of task ids */ // RTEMS TASKS rtems_task Init( rtems_task_argument argument); diff --git a/header/fsw_params.h b/header/fsw_params.h --- a/header/fsw_params.h +++ b/header/fsw_params.h @@ -140,11 +140,25 @@ typedef struct ring_node //***** // TIME -#define CLKDIV_SM_SIMULATOR (10416 - 1) // 10 ms => nominal is 1/96 = 0.010416667, 10417 - 1 = 10416 -#define TIMER_SM_SIMULATOR 1 -#define HK_PERIOD 100 // 100 * 10ms => 1s -#define SY_LFR_TIME_SYN_TIMEOUT_in_ms 2000 -#define SY_LFR_TIME_SYN_TIMEOUT_in_ticks 200 // 200 * 10 ms = 2 s +#ifdef FAST_SCHEDULER + #define CLKDIV_SM_SIMULATOR (10416 - 1) // 10 ms => nominal is 1/96 = 0.010416667, 10417 - 1 = 10416 + #define TIMER_SM_SIMULATOR 1 + #define HK_PERIOD 1000 // 1000 * 1ms = 1s + #define SY_LFR_TIME_SYN_TIMEOUT_in_ms 2000 + #define SY_LFR_TIME_SYN_TIMEOUT_in_ticks 2000 // 2000 * 1ms = 2s + #define SPOOL_TIMEOUT_in_ms 10 + #define SPOOL_TIMEOUT_in_ticks 5 // 10 * 1ms = 10ms + #define STAT_TASK_PERIOD 10000 // 10000 * 1ms = 10s +#else + #define CLKDIV_SM_SIMULATOR (10416 - 1) // 10 ms => nominal is 1/96 = 0.010416667, 10417 - 1 = 10416 + #define TIMER_SM_SIMULATOR 1 + #define HK_PERIOD 100 // 100 * 10ms = 1s + #define SY_LFR_TIME_SYN_TIMEOUT_in_ms 2000 + #define SY_LFR_TIME_SYN_TIMEOUT_in_ticks 200 // 200 * 10 ms = 2 s + #define SPOOL_TIMEOUT_in_ms 10 + #define SPOOL_TIMEOUT_in_ticks 1 // 200 * 10 ms = 2 s + #define STAT_TASK_PERIOD 1000 // 1000 * 10ms = 10s +#endif //********** // LPP CODES @@ -173,6 +187,7 @@ typedef struct ring_node #define TASKID_PRC1 17 #define TASKID_AVF2 18 #define TASKID_PRC2 19 +#define TASKID_SPOO 20 #define TASK_PRIORITY_SPIQ 5 #define TASK_PRIORITY_WTDG 20 @@ -191,6 +206,7 @@ typedef struct ring_node #define TASK_PRIORITY_PRC1 100 #define TASK_PRIORITY_AVF2 110 #define TASK_PRIORITY_PRC2 110 +#define TASK_PRIORITY_SPOO 150 #define TASK_PRIORITY_STAT 200 #define TASK_PRIORITY_DUMB 200 diff --git a/header/fsw_spool.h b/header/fsw_spool.h new file mode 100644 --- /dev/null +++ b/header/fsw_spool.h @@ -0,0 +1,64 @@ +#ifndef FSW_SPOOL_H_INCLUDED +#define FSW_SPOOL_H_INCLUDED + +#include +#include + +#include "fsw_params.h" +#include "fsw_processing.h" + +rtems_name name_spool_rate_monotonic; // name of the SPOOL rate monotonic +rtems_id spool_period_id; // id of the SPOOL rate monotonic period + +extern unsigned char lfrCurrentMode; + +extern waveform_picker_regs_new_t *waveform_picker_regs; +extern spectral_matrix_regs_t *spectral_matrix_regs; + +// WAVEFORMS +extern ring_node *current_ring_node_f0; +extern ring_node *ring_node_to_send_swf_f0; +extern ring_node *current_ring_node_f1; +extern ring_node *ring_node_to_send_swf_f1; +extern ring_node *ring_node_to_send_cwf_f1; +extern ring_node *current_ring_node_f2; +extern ring_node *ring_node_to_send_swf_f2; +extern ring_node *ring_node_to_send_cwf_f2; +extern ring_node *current_ring_node_f3; +extern ring_node *ring_node_to_send_cwf_f3; + +// SPECTRAL MATRICES +unsigned int spool_nb_sm_f0; +unsigned int spool_nb_sm_f1; +extern ring_node_sm *current_ring_node_sm_f0; +extern ring_node_sm *current_ring_node_sm_f1; +extern ring_node_sm *current_ring_node_sm_f2; +extern ring_node_sm *ring_node_for_averaging_sm_f0; +extern ring_node_sm *ring_node_for_averaging_sm_f1; +extern ring_node_sm *ring_node_for_averaging_sm_f2; + +extern rtems_id Task_id[]; /* array of task ids */ + +extern bool swf_f0_ready; +extern bool swf_f1_ready; +extern bool swf_f2_ready; + +extern bool wake_up_task_wfrm; +extern bool wake_up_task_cwf_f1; +extern bool wake_up_task_cwf_f2_burst; +extern bool wake_up_task_cwf_f2_sbm2; +extern bool wake_up_task_cwf_f3; + +//*********** +// RTEMS_TASK +rtems_task spoo_task( rtems_task_argument argument ); + +// OTHER FUNCTIONS +void spool_waveforms( void ); +void spool_spectral_matrices_f0( void ); +void spool_spectral_matrices_f1( void ); +void spool_spectral_matrices_f2( void ); +void spool_spectral_matrices( void ); +void spool_reset_nb_sm( void ); + +#endif // FSW_SPOOL_H_INCLUDED 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 @@ -60,10 +60,14 @@ extern struct param_local_str param_loca extern time_management_regs_t *time_management_regs; extern spectral_matrix_regs_t *spectral_matrix_regs; -extern rtems_name misc_name[5]; -extern rtems_id Task_id[20]; /* array of task ids */ +extern rtems_name misc_name[]; +extern rtems_id Task_id[]; /* array of task ids */ // ISR +void spectral_matrices_isr_f0( void ); +void spectral_matrices_isr_f1( void ); +void spectral_matrices_isr_f2( void ); +void spectral_matrix_isr_error_handler( void ); rtems_isr spectral_matrices_isr( rtems_vector_number vector ); rtems_isr spectral_matrices_isr_simu( rtems_vector_number vector ); diff --git a/header/tc_handler.h b/header/tc_handler.h --- a/header/tc_handler.h +++ b/header/tc_handler.h @@ -42,7 +42,9 @@ int enter_mode( unsigned char mode , uns int restart_science_tasks(unsigned char lfrRequestedMode ); int suspend_science_tasks(); void launch_waveform_picker(unsigned char mode , unsigned int transitionCoarseTime); +void launch_waveform_picker_spool(unsigned char mode , unsigned int transitionCoarseTime); void launch_spectral_matrix( void ); +void launch_spectral_matrix_spool( void ); void launch_spectral_matrix_simu( void ); void set_irq_on_new_ready_matrix(unsigned char value ); void set_run_matrix_spectral( unsigned char value ); diff --git a/header/wf_handler.h b/header/wf_handler.h --- a/header/wf_handler.h +++ b/header/wf_handler.h @@ -32,7 +32,7 @@ extern struct param_local_str param_loca extern unsigned short sequenceCounters_SCIENCE_NORMAL_BURST; extern unsigned short sequenceCounters_SCIENCE_SBM1_SBM2; -extern rtems_id Task_id[20]; /* array of task ids */ +extern rtems_id Task_id[]; /* array of task ids */ extern unsigned char lfrCurrentMode; @@ -40,6 +40,7 @@ extern unsigned char lfrCurrentMode; // RTEMS_ISR void reset_extractSWF( void ); rtems_isr waveforms_isr( rtems_vector_number vector ); +rtems_isr waveforms_isr_alt( rtems_vector_number vector ); //*********** // RTEMS_TASK diff --git a/src/fsw_globals.c b/src/fsw_globals.c --- a/src/fsw_globals.c +++ b/src/fsw_globals.c @@ -25,8 +25,8 @@ // RTEMS GLOBAL VARIABLES rtems_name misc_name[5]; rtems_id misc_id[5]; -rtems_name Task_name[20]; /* array of task names */ -rtems_id Task_id[20]; /* array of task ids */ +rtems_name Task_name[21]; /* array of task names */ +rtems_id Task_id[21]; /* array of task ids */ unsigned int maxCount; int fdSPW = 0; int fdUART = 0; diff --git a/src/fsw_init.c b/src/fsw_init.c --- a/src/fsw_init.c +++ b/src/fsw_init.c @@ -26,7 +26,7 @@ #define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER #define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER -#define CONFIGURE_MAXIMUM_TASKS 20 +#define CONFIGURE_MAXIMUM_TASKS 21 #define CONFIGURE_RTEMS_INIT_TASKS_TABLE #define CONFIGURE_EXTRA_TASK_STACKS (3 * RTEMS_MINIMUM_STACK_SIZE) #define CONFIGURE_LIBIO_MAXIMUM_FILE_DESCRIPTORS 32 @@ -40,6 +40,9 @@ #ifdef PRINT_STACK_REPORT #define CONFIGURE_STACK_CHECKER_ENABLED #endif +#ifdef FAST_SCHEDULER + #define CONFIGURE_MICROSECONDS_PER_TICK 1000 /* 1 millisecond */ +#endif #include @@ -194,13 +197,13 @@ rtems_task Init( rtems_task_argument ign //******************************* // configure IRQ handling for the waveform picker unit - status = rtems_interrupt_catch( waveforms_isr, + status = rtems_interrupt_catch( waveforms_isr_alt, IRQ_SPARC_WAVEFORM_PICKER, &old_isr_handler) ; // configure IRQ handling for the spectral matrices unit - status = rtems_interrupt_catch( spectral_matrices_isr, - IRQ_SPARC_SPECTRAL_MATRIX, - &old_isr_handler) ; +// status = rtems_interrupt_catch( spectral_matrices_isr, +// IRQ_SPARC_SPECTRAL_MATRIX, +// &old_isr_handler) ; // if the spacewire link is not up then send an event to the SPIQ task for link recovery if ( status_spw != RTEMS_SUCCESSFUL ) @@ -277,9 +280,11 @@ void create_names( void ) // create all Task_name[TASKID_PRC1] = rtems_build_name( 'P', 'R', 'C', '1' ); Task_name[TASKID_AVF2] = rtems_build_name( 'A', 'V', 'F', '2' ); Task_name[TASKID_PRC2] = rtems_build_name( 'P', 'R', 'C', '2' ); + Task_name[TASKID_SPOO] = rtems_build_name( 'S', 'P', 'O', 'O' ); // rate monotonic period names - name_hk_rate_monotonic = rtems_build_name( 'H', 'O', 'U', 'S' ); + name_hk_rate_monotonic = rtems_build_name( 'R', '_', 'H', 'K' ); + name_spool_rate_monotonic = rtems_build_name( 'R', '_', 'S', 'P' ); misc_name[QUEUE_RECV] = rtems_build_name( 'Q', '_', 'R', 'V' ); misc_name[QUEUE_SEND] = rtems_build_name( 'Q', '_', 'S', 'D' ); @@ -467,6 +472,14 @@ int create_all_tasks( void ) // create a RTEMS_DEFAULT_ATTRIBUTES, &Task_id[TASKID_HOUS] ); } + if (status == RTEMS_SUCCESSFUL) // SPOO + { + status = rtems_task_create( + Task_name[TASKID_SPOO], TASK_PRIORITY_SPOO, RTEMS_MINIMUM_STACK_SIZE, + RTEMS_DEFAULT_MODES | RTEMS_NO_PREEMPT, + RTEMS_DEFAULT_ATTRIBUTES, &Task_id[TASKID_SPOO] + ); + } return status; } @@ -636,6 +649,13 @@ int start_all_tasks( void ) // start all BOOT_PRINTF("in INIT *** Error starting TASK_STAT\n") } } + if (status == RTEMS_SUCCESSFUL) // SPOO + { + status = rtems_task_start( Task_id[TASKID_SPOO], spoo_task, 1 ); + if (status!=RTEMS_SUCCESSFUL) { + BOOT_PRINTF("in INIT *** Error starting TASK_SPOO\n") + } + } return status; } diff --git a/src/fsw_misc.c b/src/fsw_misc.c --- a/src/fsw_misc.c +++ b/src/fsw_misc.c @@ -125,7 +125,7 @@ rtems_task stat_task(rtems_task_argument j = 0; BOOT_PRINTF("in STAT *** \n") while(1){ - rtems_task_wake_after(1000); + rtems_task_wake_after(STAT_TASK_PERIOD); PRINTF1("%d\n", j) if (i == CPU_USAGE_REPORT_PERIOD) { // #ifdef PRINT_TASK_STATISTICS @@ -156,7 +156,7 @@ rtems_task hous_task(rtems_task_argument 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( "in HOUS *** rtems_rate_monotonic_create failed with status of %d\n", status ) } } @@ -524,6 +524,3 @@ void get_cpu_load( unsigned char *resour #endif } - - - diff --git a/src/fsw_spacewire.c b/src/fsw_spacewire.c --- a/src/fsw_spacewire.c +++ b/src/fsw_spacewire.c @@ -208,6 +208,7 @@ rtems_task send_task( rtems_task_argumen size_t size; // size of the incoming TC packet u_int32_t count; rtems_id queue_id; + rtems_interrupt_level level; status = get_message_queue_id_send( &queue_id ); if (status != RTEMS_SUCCESSFUL) @@ -221,7 +222,7 @@ rtems_task send_task( rtems_task_argumen { status = rtems_message_queue_receive( queue_id, incomingData, &size, RTEMS_WAIT, RTEMS_NO_TIMEOUT ); - + rtems_interrupt_disable( level ); if (status!=RTEMS_SUCCESSFUL) { PRINTF1("in SEND *** (1) ERR = %d\n", status) @@ -257,6 +258,8 @@ rtems_task send_task( rtems_task_argumen maxCount = count; } } + + rtems_interrupt_enable( level ); } } diff --git a/src/fsw_spool.c b/src/fsw_spool.c new file mode 100644 --- /dev/null +++ b/src/fsw_spool.c @@ -0,0 +1,276 @@ +/** Functions and tasks related to waveform packet generation. + * + * @file + * @author P. LEROY + * + * A group of functions to handle waveforms, in snapshot or continuous format.\n + * + */ + +#include "fsw_spool.h" + +//********************* +// Interrupt SubRoutine + +void spool_waveforms( void ) +{ + /** This is the interrupt sub routine called by the waveform picker core. + * + * This ISR launch different actions depending mainly on two pieces of information: + * 1. the values read in the registers of the waveform picker. + * 2. the current LFR mode. + * + */ + + rtems_status_code status; + + if ( (lfrCurrentMode == LFR_MODE_NORMAL) || (lfrCurrentMode == LFR_MODE_BURST) // in BURST the data are used to place v, e1 and e2 in the HK packet + || (lfrCurrentMode == LFR_MODE_SBM1) || (lfrCurrentMode == LFR_MODE_SBM2) ) + { // in modes other than STANDBY and BURST, send the CWF_F3 data + if ((waveform_picker_regs->status & 0x08) == 0x08){ // [1000] f3 is full + // (1) change the receiving buffer for the waveform picker + ring_node_to_send_cwf_f3 = current_ring_node_f3; + current_ring_node_f3 = current_ring_node_f3->next; + waveform_picker_regs->addr_data_f3 = current_ring_node_f3->buffer_address; + // (2) send an event for the waveforms transmission + if (rtems_event_send( Task_id[TASKID_CWF3], RTEMS_EVENT_0 ) != RTEMS_SUCCESSFUL) { + rtems_event_send( Task_id[TASKID_DUMB], RTEMS_EVENT_2 ); + } + rtems_event_send( Task_id[TASKID_DUMB], RTEMS_EVENT_2); + waveform_picker_regs->status = waveform_picker_regs->status & 0xfffff777; // reset f3 bits to 0, [1111 0111 0111 0111] + } + } + + switch(lfrCurrentMode) + { + //******** + // STANDBY + case(LFR_MODE_STANDBY): + break; + + //****** + // NORMAL + case(LFR_MODE_NORMAL): + if ( (waveform_picker_regs->status & 0xff8) != 0x00) // [1000] check the error bits + { + rtems_event_send( Task_id[TASKID_DUMB], RTEMS_EVENT_2 ); + } + if ( (waveform_picker_regs->status & 0x07) == 0x07) // [0111] check the f2, f1, f0 full bits + { + // change F0 ring node + ring_node_to_send_swf_f0 = current_ring_node_f0; + current_ring_node_f0 = current_ring_node_f0->next; + waveform_picker_regs->addr_data_f0 = current_ring_node_f0->buffer_address; + // change F1 ring node + ring_node_to_send_swf_f1 = current_ring_node_f1; + current_ring_node_f1 = current_ring_node_f1->next; + waveform_picker_regs->addr_data_f1 = current_ring_node_f1->buffer_address; + // change F2 ring node + ring_node_to_send_swf_f2 = current_ring_node_f2; + current_ring_node_f2 = current_ring_node_f2->next; + waveform_picker_regs->addr_data_f2 = current_ring_node_f2->buffer_address; + // + if (rtems_event_send( Task_id[TASKID_WFRM], RTEMS_EVENT_MODE_NORMAL ) != RTEMS_SUCCESSFUL) + { + rtems_event_send( Task_id[TASKID_DUMB], RTEMS_EVENT_2 ); + } + waveform_picker_regs->status = waveform_picker_regs->status & 0xfffff888; // [1000 1000 1000] + } + break; + + //****** + // BURST + case(LFR_MODE_BURST): + if ( (waveform_picker_regs->status & 0x04) == 0x04 ){ // [0100] check the f2 full bit + // (1) change the receiving buffer for the waveform picker + ring_node_to_send_cwf_f2 = current_ring_node_f2; + current_ring_node_f2 = current_ring_node_f2->next; + waveform_picker_regs->addr_data_f2 = current_ring_node_f2->buffer_address; + // (2) send an event for the waveforms transmission + if (rtems_event_send( Task_id[TASKID_CWF2], RTEMS_EVENT_MODE_BURST ) != RTEMS_SUCCESSFUL) { + rtems_event_send( Task_id[TASKID_DUMB], RTEMS_EVENT_2 ); + } + waveform_picker_regs->status = waveform_picker_regs->status & 0xfffffbbb; // [1111 1011 1011 1011] f2 bit = 0 + } + break; + + //***** + // SBM1 + case(LFR_MODE_SBM1): + if ( (waveform_picker_regs->status & 0x02) == 0x02 ) { // [0010] check the f1 full bit + // (1) change the receiving buffer for the waveform picker + ring_node_to_send_cwf_f1 = current_ring_node_f1; + current_ring_node_f1 = current_ring_node_f1->next; + waveform_picker_regs->addr_data_f1 = current_ring_node_f1->buffer_address; + // (2) send an event for the the CWF1 task for transmission (and snapshot extraction if needed) + status = rtems_event_send( Task_id[TASKID_CWF1], RTEMS_EVENT_MODE_SBM1 ); + waveform_picker_regs->status = waveform_picker_regs->status & 0xfffffddd; // [1111 1101 1101 1101] f1 bits = 0 + } + if ( (waveform_picker_regs->status & 0x01) == 0x01 ) { // [0001] check the f0 full bit + swf_f0_ready = true; + waveform_picker_regs->status = waveform_picker_regs->status & 0xfffffeee; // [1111 1110 1110 1110] f0 bits = 0 + } + if ( (waveform_picker_regs->status & 0x04) == 0x04 ) { // [0100] check the f2 full bit + swf_f2_ready = true; + waveform_picker_regs->status = waveform_picker_regs->status & 0xfffffbbb; // [1111 1011 1011 1011] f2 bits = 0 + } + break; + + //***** + // SBM2 + case(LFR_MODE_SBM2): + if ( (waveform_picker_regs->status & 0x04) == 0x04 ){ // [0100] check the f2 full bit + // (1) change the receiving buffer for the waveform picker + ring_node_to_send_cwf_f2 = current_ring_node_f2; + current_ring_node_f2 = current_ring_node_f2->next; + waveform_picker_regs->addr_data_f2 = current_ring_node_f2->buffer_address; + // (2) send an event for the waveforms transmission + status = rtems_event_send( Task_id[TASKID_CWF2], RTEMS_EVENT_MODE_SBM2 ); + waveform_picker_regs->status = waveform_picker_regs->status & 0xfffffbbb; // [1111 1011 1011 1011] f2 bit = 0 + } + if ( (waveform_picker_regs->status & 0x01) == 0x01 ) { // [0001] check the f0 full bit + swf_f0_ready = true; + waveform_picker_regs->status = waveform_picker_regs->status & 0xfffffeee; // [1111 1110 1110 1110] f0 bits = 0 + } + if ( (waveform_picker_regs->status & 0x02) == 0x02 ) { // [0010] check the f1 full bit + swf_f1_ready = true; + waveform_picker_regs->status = waveform_picker_regs->status & 0xfffffddd; // [1111 1101 1101 1101] f1, f0 bits = 0 + } + break; + + //******** + // DEFAULT + default: + break; + } +} + +void spool_waveforms_alt( void ) +{ + // WFRM + if (wake_up_task_wfrm == true) + { + rtems_event_send( Task_id[TASKID_WFRM], RTEMS_EVENT_MODE_NORMAL ); + wake_up_task_wfrm = false; + } + // CWF_F1 + if (wake_up_task_cwf_f1 == true) + { + rtems_event_send( Task_id[TASKID_CWF1], RTEMS_EVENT_MODE_SBM1 ); + wake_up_task_cwf_f1 = false; + } + // CWF_F2 BURST + if (wake_up_task_cwf_f2_burst == true) + { + rtems_event_send( Task_id[TASKID_CWF2], RTEMS_EVENT_MODE_BURST ); + wake_up_task_cwf_f2_burst = false; + } + // CWF_F2 SBM2 + if (wake_up_task_cwf_f2_sbm2 == true) + { + rtems_event_send( Task_id[TASKID_CWF2], RTEMS_EVENT_MODE_SBM2 ); + wake_up_task_cwf_f2_sbm2 = false; + } + // CWF_F3 + if (wake_up_task_cwf_f3 == true) + { + rtems_event_send( Task_id[TASKID_CWF3], RTEMS_EVENT_0 ); + wake_up_task_cwf_f3 = false; + } +} + +void spool_spectral_matrices( void ) +{ + // STATUS REGISTER + // input_fifo_write(2) *** input_fifo_write(1) *** input_fifo_write(0) + // 10 9 8 + // buffer_full ** bad_component_err ** f2_1 ** f2_0 ** f1_1 ** f1_0 ** f0_1 ** f0_0 + // 7 6 5 4 3 2 1 0 + + unsigned char status_f0; + unsigned char status_f1; + unsigned char status_f2; + static unsigned int counter = 0; + + rtems_interrupt_level level; + + rtems_interrupt_disable( level ); + + status_f0 = spectral_matrix_regs->status & 0x03; // [0011] get the status_ready_matrix_f0_x bits + status_f1 = (spectral_matrix_regs->status & 0x0c) >> 2; // [0011] get the status_ready_matrix_f0_x bits + status_f2 = (spectral_matrix_regs->status & 0x30) >> 4; // [0011] get the status_ready_matrix_f0_x bits + +// if ( status_f0 == 0x03) +// { +// printf("%d \n", counter); +// } + if ( status_f1 == 0x03) + { + printf("f1 %d \n", counter); + } + if ( status_f2 == 0x03) + { + printf("f2 %d \n", counter); + } + + spectral_matrices_isr_f0(); + + spectral_matrices_isr_f1(); + + spectral_matrices_isr_f2(); + + spectral_matrix_isr_error_handler(); + + rtems_interrupt_enable( level ); + + counter = counter + 1; +} + +//************ +// RTEMS TASKS + +rtems_task spoo_task(rtems_task_argument argument) +{ + rtems_status_code status; + + BOOT_PRINTF("in SPOOL ***\n") + + if (rtems_rate_monotonic_ident( name_spool_rate_monotonic, &spool_period_id) != RTEMS_SUCCESSFUL) { + status = rtems_rate_monotonic_create( name_spool_rate_monotonic, &spool_period_id ); + if( status != RTEMS_SUCCESSFUL ) { + PRINTF1( "in SPOO *** rtems_rate_monotonic_create failed with status %d\n", status ) + } + } + + status = rtems_rate_monotonic_cancel( spool_period_id ); + if( status != RTEMS_SUCCESSFUL ) + { + PRINTF1( "ERR *** in SPOOL *** rtems_rate_monotonic_cancel(spool_period_id) ***code: %d\n", status ) + } + else + { + DEBUG_PRINTF("OK *** in SPOOL *** rtems_rate_monotonic_cancel(spool_period_id)\n") + } + + while(1){ // launch the rate monotonic task +// status = rtems_rate_monotonic_period( spool_period_id, SPOOL_TIMEOUT_in_ticks ); + rtems_task_wake_after( SPOOL_TIMEOUT_in_ticks / 2 ); + spool_waveforms_alt(); + spool_spectral_matrices(); +// if ( status != RTEMS_SUCCESSFUL ) +// { +// PRINTF1( "in SPOOL *** ERR period: %d\n", status); +// } +// else +// { +// spool_waveforms(); +// spool_spectral_matrices(); +// } + } + + PRINTF("in SPOOL *** deleting task\n") + + status = rtems_task_delete( RTEMS_SELF ); // should not return + printf( "rtems_task_delete returned with status of %d.\n", status ); + return; +} 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 @@ -173,10 +173,12 @@ void spectral_matrices_isr_f2( void ) void spectral_matrix_isr_error_handler( void ) { - if (spectral_matrix_regs->status & 0x7c0) // [0111 1100 0000] - { - rtems_event_send( Task_id[TASKID_DUMB], RTEMS_EVENT_8 ); - } +// if (spectral_matrix_regs->status & 0x7c0) // [0111 1100 0000] +// { +// rtems_event_send( Task_id[TASKID_DUMB], RTEMS_EVENT_8 ); +// } + + spectral_matrix_regs->status = spectral_matrix_regs->status & 0x83f; } rtems_isr spectral_matrices_isr( rtems_vector_number vector ) diff --git a/src/tc_handler.c b/src/tc_handler.c --- a/src/tc_handler.c +++ b/src/tc_handler.c @@ -531,9 +531,16 @@ int enter_mode( unsigned char mode, unsi maxCount = 0; #endif status = restart_science_tasks( mode ); + //**************** + // WAVEFORM PICKER launch_waveform_picker( mode, transitionCoarseTime ); - launch_spectral_matrix( ); +// launch_waveform_picker_spool( mode, transitionCoarseTime ); + + //****************** + // SPECTRAL MATRICES +// launch_spectral_matrix( ); // launch_spectral_matrix_simu( ); + launch_spectral_matrix_spool( ); } else if ( mode == LFR_MODE_STANDBY ) { @@ -575,7 +582,7 @@ int restart_science_tasks(unsigned char * */ - rtems_status_code status[10]; + rtems_status_code status[11]; rtems_status_code ret; ret = RTEMS_SUCCESSFUL; @@ -640,11 +647,19 @@ int restart_science_tasks(unsigned char PRINTF1("in restart_science_task *** PRC2 ERR %d\n", status[9]) } + status[10] = rtems_task_restart( Task_id[TASKID_SPOO], 1 ); + if (status[10] != RTEMS_SUCCESSFUL) + { + PRINTF1("in restart_science_task *** SPOO ERR %d\n", status[10]) + } + + if ( (status[0] != RTEMS_SUCCESSFUL) || (status[1] != RTEMS_SUCCESSFUL) || (status[2] != RTEMS_SUCCESSFUL) || (status[3] != RTEMS_SUCCESSFUL) || (status[4] != RTEMS_SUCCESSFUL) || (status[5] != RTEMS_SUCCESSFUL) || (status[6] != RTEMS_SUCCESSFUL) || (status[7] != RTEMS_SUCCESSFUL) || - (status[8] != RTEMS_SUCCESSFUL) || (status[9] != RTEMS_SUCCESSFUL) ) + (status[8] != RTEMS_SUCCESSFUL) || (status[9] != RTEMS_SUCCESSFUL) || + (status[10]!= RTEMS_SUCCESSFUL) ) { ret = RTEMS_UNSATISFIED; } @@ -742,10 +757,35 @@ int suspend_science_tasks() PRINTF1("in suspend_science_task *** CWF1 ERR %d\n", status) } } + if (status == RTEMS_SUCCESSFUL) // suspend SPOO + { + status = rtems_task_suspend( Task_id[TASKID_SPOO] ); + if (status != RTEMS_SUCCESSFUL) + { + PRINTF1("in suspend_science_task *** SPOO ERR %d\n", status) + } + } return status; } +void launch_waveform_picker_spool( unsigned char mode, unsigned int transitionCoarseTime ) +{ + WFP_reset_current_ring_nodes(); + reset_waveform_picker_regs(); + set_wfp_burst_enable_register( mode ); + + waveform_picker_regs->run_burst_enable = waveform_picker_regs->run_burst_enable | 0x80; // [1000 0000] + if (transitionCoarseTime == 0) + { + waveform_picker_regs->start_date = time_management_regs->coarse_time; + } + else + { + waveform_picker_regs->start_date = transitionCoarseTime; + } +} + void launch_waveform_picker( unsigned char mode, unsigned int transitionCoarseTime ) { WFP_reset_current_ring_nodes(); @@ -766,6 +806,20 @@ void launch_waveform_picker( unsigned ch } } +void launch_spectral_matrix_spool( void ) +{ + SM_reset_current_ring_nodes(); + reset_spectral_matrix_regs(); + reset_nb_sm(); + + struct grgpio_regs_str *grgpio_regs = (struct grgpio_regs_str *) REGS_ADDR_GRGPIO; + grgpio_regs->io_port_direction_register = + grgpio_regs->io_port_direction_register | 0x01; // [0000 0001], 0 = output disabled, 1 = output enabled + grgpio_regs->io_port_output_register = grgpio_regs->io_port_output_register & 0xfffffffe; // set the bit 0 to 0 + set_irq_on_new_ready_matrix( 0 ); + set_run_matrix_spectral( 1 ); +} + void launch_spectral_matrix( void ) { SM_reset_current_ring_nodes(); diff --git a/src/wf_handler.c b/src/wf_handler.c --- a/src/wf_handler.c +++ b/src/wf_handler.c @@ -44,6 +44,12 @@ bool swf_f0_ready = false; bool swf_f1_ready = false; bool swf_f2_ready = false; +bool wake_up_task_wfrm = false; +bool wake_up_task_cwf_f1 = false; +bool wake_up_task_cwf_f2_burst = false; +bool wake_up_task_cwf_f2_sbm2 = false; +bool wake_up_task_cwf_f3 = false; + int wf_snap_extracted[ (NB_SAMPLES_PER_SNAPSHOT * NB_WORDS_SWF_BLK) + TIME_OFFSET ]; //********************* @@ -190,6 +196,135 @@ rtems_isr waveforms_isr( rtems_vector_nu } } +rtems_isr waveforms_isr_alt( rtems_vector_number vector ) +{ + /** This is the interrupt sub routine called by the waveform picker core. + * + * This ISR launch different actions depending mainly on two pieces of information: + * 1. the values read in the registers of the waveform picker. + * 2. the current LFR mode. + * + */ + + rtems_interrupt_level level; + + rtems_interrupt_disable( level ); + + if ( (lfrCurrentMode == LFR_MODE_NORMAL) || (lfrCurrentMode == LFR_MODE_BURST) // in BURST the data are used to place v, e1 and e2 in the HK packet + || (lfrCurrentMode == LFR_MODE_SBM1) || (lfrCurrentMode == LFR_MODE_SBM2) ) + { // in modes other than STANDBY and BURST, send the CWF_F3 data + if ((waveform_picker_regs->status & 0x08) == 0x08){ // [1000] f3 is full + // (1) change the receiving buffer for the waveform picker + ring_node_to_send_cwf_f3 = current_ring_node_f3; + current_ring_node_f3 = current_ring_node_f3->next; + waveform_picker_regs->addr_data_f3 = current_ring_node_f3->buffer_address; + // (2) send an event for the waveforms transmission + wake_up_task_cwf_f3 = true; + waveform_picker_regs->status = waveform_picker_regs->status & 0xfffff777; // reset f3 bits to 0, [1111 0111 0111 0111] + } + } + + switch(lfrCurrentMode) + { + //******** + // STANDBY + case(LFR_MODE_STANDBY): + break; + + //****** + // NORMAL + case(LFR_MODE_NORMAL): + if ( (waveform_picker_regs->status & 0xff8) != 0x00) // [1000] check the error bits + { + rtems_event_send( Task_id[TASKID_DUMB], RTEMS_EVENT_2 ); + } + if ( (waveform_picker_regs->status & 0x07) == 0x07) // [0111] check the f2, f1, f0 full bits + { + // change F0 ring node + ring_node_to_send_swf_f0 = current_ring_node_f0; + current_ring_node_f0 = current_ring_node_f0->next; + waveform_picker_regs->addr_data_f0 = current_ring_node_f0->buffer_address; + // change F1 ring node + ring_node_to_send_swf_f1 = current_ring_node_f1; + current_ring_node_f1 = current_ring_node_f1->next; + waveform_picker_regs->addr_data_f1 = current_ring_node_f1->buffer_address; + // change F2 ring node + ring_node_to_send_swf_f2 = current_ring_node_f2; + current_ring_node_f2 = current_ring_node_f2->next; + waveform_picker_regs->addr_data_f2 = current_ring_node_f2->buffer_address; + // + wake_up_task_wfrm = true; + waveform_picker_regs->status = waveform_picker_regs->status & 0xfffff888; // [1000 1000 1000] + } + break; + + //****** + // BURST + case(LFR_MODE_BURST): + if ( (waveform_picker_regs->status & 0x04) == 0x04 ){ // [0100] check the f2 full bit + // (1) change the receiving buffer for the waveform picker + ring_node_to_send_cwf_f2 = current_ring_node_f2; + current_ring_node_f2 = current_ring_node_f2->next; + waveform_picker_regs->addr_data_f2 = current_ring_node_f2->buffer_address; + // (2) send an event for the waveforms transmission + wake_up_task_cwf_f2_burst = true; + waveform_picker_regs->status = waveform_picker_regs->status & 0xfffffbbb; // [1111 1011 1011 1011] f2 bit = 0 + } + break; + + //***** + // SBM1 + case(LFR_MODE_SBM1): + if ( (waveform_picker_regs->status & 0x02) == 0x02 ) { // [0010] check the f1 full bit + // (1) change the receiving buffer for the waveform picker + ring_node_to_send_cwf_f1 = current_ring_node_f1; + current_ring_node_f1 = current_ring_node_f1->next; + waveform_picker_regs->addr_data_f1 = current_ring_node_f1->buffer_address; + // (2) send an event for the the CWF1 task for transmission (and snapshot extraction if needed) + wake_up_task_cwf_f1 = true; + waveform_picker_regs->status = waveform_picker_regs->status & 0xfffffddd; // [1111 1101 1101 1101] f1 bits = 0 + } + if ( (waveform_picker_regs->status & 0x01) == 0x01 ) { // [0001] check the f0 full bit + swf_f0_ready = true; + waveform_picker_regs->status = waveform_picker_regs->status & 0xfffffeee; // [1111 1110 1110 1110] f0 bits = 0 + } + if ( (waveform_picker_regs->status & 0x04) == 0x04 ) { // [0100] check the f2 full bit + swf_f2_ready = true; + waveform_picker_regs->status = waveform_picker_regs->status & 0xfffffbbb; // [1111 1011 1011 1011] f2 bits = 0 + } + break; + + //***** + // SBM2 + case(LFR_MODE_SBM2): + if ( (waveform_picker_regs->status & 0x04) == 0x04 ){ // [0100] check the f2 full bit + // (1) change the receiving buffer for the waveform picker + ring_node_to_send_cwf_f2 = current_ring_node_f2; + current_ring_node_f2 = current_ring_node_f2->next; + waveform_picker_regs->addr_data_f2 = current_ring_node_f2->buffer_address; + // (2) send an event for the waveforms transmission + wake_up_task_cwf_f2_sbm2 = true; + waveform_picker_regs->status = waveform_picker_regs->status & 0xfffffbbb; // [1111 1011 1011 1011] f2 bit = 0 + } + if ( (waveform_picker_regs->status & 0x01) == 0x01 ) { // [0001] check the f0 full bit + swf_f0_ready = true; + waveform_picker_regs->status = waveform_picker_regs->status & 0xfffffeee; // [1111 1110 1110 1110] f0 bits = 0 + } + if ( (waveform_picker_regs->status & 0x02) == 0x02 ) { // [0010] check the f1 full bit + swf_f1_ready = true; + waveform_picker_regs->status = waveform_picker_regs->status & 0xfffffddd; // [1111 1101 1101 1101] f1, f0 bits = 0 + } + break; + + //******** + // DEFAULT + default: + break; + } + + rtems_interrupt_enable( level ); +} + //************ // RTEMS TASKS @@ -379,6 +514,7 @@ rtems_task cwf1_task(rtems_task_argument rtems_event_set event_out; rtems_id queue_id; rtems_status_code status; + rtems_interrupt_level level = 0; init_header_continuous_wf_table( SID_SBM1_CWF_F1, headerCWF_F1 ); @@ -390,10 +526,17 @@ rtems_task cwf1_task(rtems_task_argument BOOT_PRINTF("in CWF1 ***\n") + printf("(0) level = %x\n", (unsigned int) level); + while(1){ // wait for an RTEMS_EVENT rtems_event_receive( RTEMS_EVENT_MODE_SBM1, RTEMS_WAIT | RTEMS_EVENT_ANY, RTEMS_NO_TIMEOUT, &event_out); + + rtems_interrupt_disable( level ); + + printf("(1) level = %x\n", (unsigned int) level); + send_waveform_CWF( (volatile int*) ring_node_to_send_cwf_f1->buffer_address, SID_SBM1_CWF_F1, headerCWF_F1, queue_id ); // launch snapshot extraction if needed if (extractSWF == true) @@ -414,6 +557,10 @@ rtems_task cwf1_task(rtems_task_argument swf_f1_ready = false; swf_f2_ready = false; } + + rtems_interrupt_enable( level ); + + printf("(2) level = %x\n", (unsigned int) level); } }