/** Functions related to data processing. * * @file * @author P. LEROY * * These function are related to data processing, i.e. spectral matrices averaging and basic parameters computation. * */ #include #include "fsw_processing_globals.c" //************************ // spectral matrices rings ring_node sm_ring_f0[NB_RING_NODES_ASM_F0]; ring_node sm_ring_f1[NB_RING_NODES_ASM_F1]; ring_node sm_ring_f2[NB_RING_NODES_ASM_F2]; ring_node *current_ring_node_sm_f0; ring_node *ring_node_for_averaging_sm_f0; ring_node *current_ring_node_sm_f1; ring_node *current_ring_node_sm_f2; BP1_t data_BP1[ NB_BINS_COMPRESSED_SM_F0 ]; float averaged_sm_f0[ TOTAL_SIZE_SM ]; char averaged_sm_f0_char[ TOTAL_SIZE_SM * 2 ]; float compressed_sm_f0[ TOTAL_SIZE_COMPRESSED_MATRIX_f0 ]; unsigned int nb_sm_f0; void init_sm_rings( void ) { unsigned char i; // F0 RING sm_ring_f0[0].next = (ring_node*) &sm_ring_f0[1]; sm_ring_f0[0].previous = (ring_node*) &sm_ring_f0[NB_RING_NODES_ASM_F0-1]; sm_ring_f0[0].buffer_address = (int) &sm_f0[0][0]; sm_ring_f0[NB_RING_NODES_ASM_F0-1].next = (ring_node*) &sm_ring_f0[0]; sm_ring_f0[NB_RING_NODES_ASM_F0-1].previous = (ring_node*) &sm_ring_f0[NB_RING_NODES_ASM_F0-2]; sm_ring_f0[NB_RING_NODES_ASM_F0-1].buffer_address = (int) &sm_f0[NB_RING_NODES_ASM_F0-1][0]; for(i=1; imatrixF0_Address0 = sm_ring_f0[0].buffer_address; DEBUG_PRINTF1("spectral_matrix_regs->matrixF0_Address0 @%x\n", spectral_matrix_regs->matrixF0_Address0) } void reset_current_sm_ring_nodes( void ) { current_ring_node_sm_f0 = sm_ring_f0; ring_node_for_averaging_sm_f0 = sm_ring_f0; } //*********************************************************** // Interrupt Service Routine for spectral matrices processing void reset_nb_sm_f0( void ) { nb_sm_f0 = 0; } rtems_isr spectral_matrices_isr( rtems_vector_number vector ) { // unsigned char status; // unsigned char i; // status = spectral_matrix_regs->status; //[f2 f1 f0_1 f0_0] // for (i=0; i<4; i++) // { // if ( ( (status >> i) & 0x01) == 1) // (1) buffer rotation // { // switch(i) // { // case 0: // current_ring_node_sm_f0 = current_ring_node_sm_f0->next; // spectral_matrix_regs->matrixF0_Address0 = current_ring_node_sm_f0->buffer_address; // spectral_matrix_regs->status = spectral_matrix_regs->status & 0xfffffffe; // nb_interrupt_f0 = nb_interrupt_f0 + 1; // if (nb_interrupt_f0 == NB_SM_TO_RECEIVE_BEFORE_AVF0 ){ // ring_node_for_averaging_sm_f0 = current_ring_node_sm_f0; // if (rtems_event_send( Task_id[TASKID_AVF0], RTEMS_EVENT_0 ) != RTEMS_SUCCESSFUL) // { // rtems_event_send( Task_id[TASKID_DUMB], RTEMS_EVENT_3 ); // } // nb_interrupt_f0 = 0; // } // break; // case 1: // break; // case 2: // break; // default: // break; // } // } // } // // reset error codes to 0 // spectral_matrix_regs->status = spectral_matrix_regs->status & 0xffffffcf; // [1100 1111] } rtems_isr spectral_matrices_isr_simu( rtems_vector_number vector ) { //current_ring_node_sm_f0 = current_ring_node_sm_f0->next; //spectral_matrix_regs->matrixF0_Address0 = current_ring_node_sm_f0->buffer_address; //spectral_matrix_regs->status = spectral_matrix_regs->status & 0xfffffffe; if (nb_sm_f0 == (NB_SM_TO_RECEIVE_BEFORE_AVF0-1) ) { ring_node_for_averaging_sm_f0 = current_ring_node_sm_f0; if (rtems_event_send( Task_id[TASKID_AVF0], RTEMS_EVENT_0 ) != RTEMS_SUCCESSFUL) { rtems_event_send( Task_id[TASKID_DUMB], RTEMS_EVENT_3 ); } nb_sm_f0 = 0; } else { nb_sm_f0 = nb_sm_f0 + 1; } } //************ // RTEMS TASKS rtems_task smiq_task(rtems_task_argument argument) // process the Spectral Matrices IRQ { rtems_event_set event_out; BOOT_PRINTF("in SMIQ *** \n") while(1){ rtems_event_receive(RTEMS_EVENT_0, RTEMS_WAIT, RTEMS_NO_TIMEOUT, &event_out); // wait for an RTEMS_EVENT0 } } rtems_task spw_bppr_task(rtems_task_argument argument) { rtems_status_code status; rtems_event_set event_out; BOOT_PRINTF("in BPPR ***\n"); while( true ){ // wait for an event to begin with the processing status = rtems_event_receive(RTEMS_EVENT_0, RTEMS_WAIT, RTEMS_NO_TIMEOUT, &event_out); } } rtems_task avf0_task(rtems_task_argument argument) { int i; static int nb_average; rtems_event_set event_out; rtems_status_code status; ring_node *ring_node_tab[8]; nb_average = 0; BOOT_PRINTF("in AVFO *** \n") while(1){ rtems_event_receive(RTEMS_EVENT_0, RTEMS_WAIT, RTEMS_NO_TIMEOUT, &event_out); // wait for an RTEMS_EVENT0 ring_node_for_averaging_sm_f0 = &sm_ring_f0[NB_SM_TO_RECEIVE_BEFORE_AVF0-1]; ring_node_tab[NB_SM_TO_RECEIVE_BEFORE_AVF0-1] = ring_node_for_averaging_sm_f0; for (i=2; iprevious; ring_node_tab[NB_SM_TO_RECEIVE_BEFORE_AVF0-i] = ring_node_for_averaging_sm_f0; } for(i=0; ibuffer_address) ) [i] + ( (int *) (ring_node_tab[1]->buffer_address) ) [i] + ( (int *) (ring_node_tab[2]->buffer_address) ) [i] + ( (int *) (ring_node_tab[3]->buffer_address) ) [i] + ( (int *) (ring_node_tab[4]->buffer_address) ) [i] + ( (int *) (ring_node_tab[5]->buffer_address) ) [i] + ( (int *) (ring_node_tab[6]->buffer_address) ) [i] + ( (int *) (ring_node_tab[7]->buffer_address) ) [i]; } nb_average = nb_average + NB_SM_TO_RECEIVE_BEFORE_AVF0; if (nb_average == NB_AVERAGE_NORMAL_f0) { nb_average = 0; status = rtems_event_send( Task_id[TASKID_MATR], RTEMS_EVENT_0 ); // sending an event to the task 7, BPF0 if (status != RTEMS_SUCCESSFUL) { printf("in AVF0 *** Error sending RTEMS_EVENT_0, code %d\n", status); } } } } rtems_task bpf0_task(rtems_task_argument argument) { rtems_event_set event_out; static unsigned char LFR_BP1_F0[ NB_BINS_COMPRESSED_SM_F0 * 9 ]; BOOT_PRINTF("in BPFO *** \n") while(1){ rtems_event_receive(RTEMS_EVENT_0, RTEMS_WAIT, RTEMS_NO_TIMEOUT, &event_out); // wait for an RTEMS_EVENT0 matrix_compression(averaged_sm_f0, 0, compressed_sm_f0); BP1_set(compressed_sm_f0, NB_BINS_COMPRESSED_SM_F0, LFR_BP1_F0); } } rtems_task matr_task(rtems_task_argument argument) { spw_ioctl_pkt_send spw_ioctl_send_ASM; rtems_event_set event_out; rtems_status_code status; rtems_id queue_id; Header_TM_LFR_SCIENCE_ASM_t headerASM; init_header_asm( &headerASM ); status = get_message_queue_id_send( &queue_id ); if (status != RTEMS_SUCCESSFUL) { PRINTF1("in MATR *** ERR get_message_queue_id_send %d\n", status) } BOOT_PRINTF("in MATR *** \n") fill_averaged_spectral_matrix( ); while(1){ rtems_event_receive(RTEMS_EVENT_0, RTEMS_WAIT, RTEMS_NO_TIMEOUT, &event_out); // wait for an RTEMS_EVENT0 // 1) convert the float array in a char array convert_averaged_spectral_matrix( averaged_sm_f0, averaged_sm_f0_char); // 2) send the spectral matrix packets send_spectral_matrix( &headerASM, averaged_sm_f0_char, SID_NORM_ASM_F0, &spw_ioctl_send_ASM, queue_id); } } //***************************** // Spectral matrices processing void matrix_reset(volatile float *averaged_spec_mat) { int i; for(i=0; i abs(sx_im) ) { LFR_BP1[(i*9) + 7] = LFR_BP1[(i*9) + 1] | (0x80); // extract the sector of sx } else { LFR_BP1[(i*9) + 7] = LFR_BP1[(i*9) + 1] & (0x7f); // extract the sector of sx } //====================================================================== // BP1 phase velocity estimator == PAR_LFR_SC_BP1_VPHI_F0 == 8 bits (7+1) ny = sin(Alpha_M)*NVEC_V1 + cos(Alpha_M)*NVEC_V2; nz = NVEC_V0; bx_bx_star = cos(Alpha_M) * cos(Alpha_M) * compressed_spec_mat[i*30+10] // re S22 + sin(Alpha_M) * sin(Alpha_M) * compressed_spec_mat[i*30+18] // re S33 - 2 * sin(Alpha_M) * cos(Alpha_M) * compressed_spec_mat[i*30+12]; // re S23 nebx_re = ny * (compressed_spec_mat[(i*30) + 14] * K24_ny_re +compressed_spec_mat[(i*30) + 16] * K25_ny_re +compressed_spec_mat[(i*30) + 20] * K34_ny_re +compressed_spec_mat[(i*30) + 22] * K35_ny_re) + nz * (compressed_spec_mat[(i*30) + 14] * K24_nz_re +compressed_spec_mat[(i*30) + 16] * K25_nz_re +compressed_spec_mat[(i*30) + 20] * K34_nz_re +compressed_spec_mat[(i*30) + 22] * K35_nz_re); nebx_im = ny * (compressed_spec_mat[(i*30) + 15]*K24_ny_re +compressed_spec_mat[(i*30) + 17] * K25_ny_re +compressed_spec_mat[(i*30) + 21] * K34_ny_re +compressed_spec_mat[(i*30) + 23] * K35_ny_re) + nz * (compressed_spec_mat[(i*30) + 15] * K24_nz_im +compressed_spec_mat[(i*30) + 17] * K25_nz_im +compressed_spec_mat[(i*30) + 21] * K34_nz_im +compressed_spec_mat[(i*30) + 23] * K35_nz_im); tmp = nebx_re / bx_bx_star; LFR_BP1[(i*9) + 8] = ((unsigned char) (tmp * 128)) & 0x7f; // cf DOC for the compression if ( abs(nebx_re) > abs(nebx_im) ) { LFR_BP1[(i*9) + 8] = LFR_BP1[(i*9) + 8] | (0x80); // extract the sector of nebx } else { LFR_BP1[(i*9) + 8] = LFR_BP1[(i*9) + 8] & (0x7f); // extract the sector of nebx } } } void BP2_set_old(float * compressed_spec_mat, unsigned char nb_bins_compressed_spec_mat){ // BP2 autocorrelation int i; int aux = 0; for(i = 0; itargetLogicalAddress = CCSDS_DESTINATION_ID; header->protocolIdentifier = CCSDS_PROTOCOLE_ID; header->reserved = 0x00; header->userApplication = CCSDS_USER_APP; header->packetID[0] = (unsigned char) (TM_PACKET_ID_SCIENCE_NORMAL_BURST >> 8); header->packetID[1] = (unsigned char) (TM_PACKET_ID_SCIENCE_NORMAL_BURST); header->packetSequenceControl[0] = 0xc0; header->packetSequenceControl[1] = 0x00; header->packetLength[0] = 0x00; header->packetLength[1] = 0x00; // DATA FIELD HEADER header->spare1_pusVersion_spare2 = 0x10; header->serviceType = TM_TYPE_LFR_SCIENCE; // service type header->serviceSubType = TM_SUBTYPE_LFR_SCIENCE; // service subtype header->destinationID = TM_DESTINATION_ID_GROUND; // AUXILIARY DATA HEADER header->sid = 0x00; header->biaStatusInfo = 0x00; header->pa_lfr_pkt_cnt_asm = 0x00; header->pa_lfr_pkt_nr_asm = 0x00; header->time[0] = 0x00; header->time[0] = 0x00; header->time[0] = 0x00; header->time[0] = 0x00; header->time[0] = 0x00; header->time[0] = 0x00; header->pa_lfr_asm_blk_nr[0] = 0x00; // BLK_NR MSB header->pa_lfr_asm_blk_nr[1] = 0x00; // BLK_NR LSB } void send_spectral_matrix(Header_TM_LFR_SCIENCE_ASM_t *header, char *spectral_matrix, unsigned int sid, spw_ioctl_pkt_send *spw_ioctl_send, rtems_id queue_id) { unsigned int i; unsigned int length = 0; rtems_status_code status; for (i=0; i<2; i++) { // (1) BUILD THE DATA switch(sid) { case SID_NORM_ASM_F0: spw_ioctl_send->dlen = TOTAL_SIZE_ASM_F0_IN_BYTES / 2; spw_ioctl_send->data = &spectral_matrix[ ( (ASM_F0_INDICE_START+ (i*NB_BINS_PER_PKT_ASM_F0)) * NB_VALUES_PER_SM) * 2 ]; length = PACKET_LENGTH_TM_LFR_SCIENCE_ASM_F0; header->pa_lfr_asm_blk_nr[0] = (unsigned char) ( (NB_BINS_PER_PKT_ASM_F0) >> 8 ); // BLK_NR MSB header->pa_lfr_asm_blk_nr[1] = (unsigned char) (NB_BINS_PER_PKT_ASM_F0); // BLK_NR LSB break; case SID_NORM_ASM_F1: break; case SID_NORM_ASM_F2: break; default: PRINTF1("ERR *** in send_spectral_matrix *** unexpected sid %d\n", sid) break; } spw_ioctl_send->hlen = HEADER_LENGTH_TM_LFR_SCIENCE_ASM + CCSDS_PROTOCOLE_EXTRA_BYTES; spw_ioctl_send->hdr = (char *) header; spw_ioctl_send->options = 0; // (2) BUILD THE HEADER header->packetLength[0] = (unsigned char) (length>>8); header->packetLength[1] = (unsigned char) (length); header->sid = (unsigned char) sid; // SID header->pa_lfr_pkt_cnt_asm = 2; header->pa_lfr_pkt_nr_asm = (unsigned char) (i+1); // (3) SET PACKET TIME header->time[0] = (unsigned char) (time_management_regs->coarse_time>>24); header->time[1] = (unsigned char) (time_management_regs->coarse_time>>16); header->time[2] = (unsigned char) (time_management_regs->coarse_time>>8); header->time[3] = (unsigned char) (time_management_regs->coarse_time); header->time[4] = (unsigned char) (time_management_regs->fine_time>>8); header->time[5] = (unsigned char) (time_management_regs->fine_time); // header->acquisitionTime[0] = (unsigned char) (time_management_regs->coarse_time>>24); header->acquisitionTime[1] = (unsigned char) (time_management_regs->coarse_time>>16); header->acquisitionTime[2] = (unsigned char) (time_management_regs->coarse_time>>8); header->acquisitionTime[3] = (unsigned char) (time_management_regs->coarse_time); header->acquisitionTime[4] = (unsigned char) (time_management_regs->fine_time>>8); header->acquisitionTime[5] = (unsigned char) (time_management_regs->fine_time); // (4) SEND PACKET status = rtems_message_queue_send( queue_id, spw_ioctl_send, ACTION_MSG_SPW_IOCTL_SEND_SIZE); if (status != RTEMS_SUCCESSFUL) { printf("in send_spectral_matrix *** ERR %d\n", (int) status); } } } void convert_averaged_spectral_matrix( volatile float *input_matrix, char *output_matrix) { unsigned int i; unsigned int j; char * pt_char_input; char * pt_char_output; pt_char_input = NULL; pt_char_output = NULL; for( i=0; imatrixF0_Address0 = current_ring_node_sm_f0->buffer_address; spectral_matrix_regs->matrixFO_Address1 = current_ring_node_sm_f0->buffer_address; spectral_matrix_regs->matrixF1_Address = current_ring_node_sm_f1->buffer_address; spectral_matrix_regs->matrixF2_Address = current_ring_node_sm_f2->buffer_address; } //****************** // general functions