/** 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; }