//============================================================================== /*! \file ls_hdl.c In this file task ls_hdl is implemented together with several of its ancillary functions. This task is in charge of executing several OBS commands and specifically all the long commands requiring interaction with the LS subsystems. When not running the task is in wait state on the LS_HDL_QUEUE. To start a command the cmd_seq task puts a the corresponding TC packets into the queue. A command is normally executed in several steps. Upon reception of the TC packet the task ls_hdl calls a function implementing the first step of the command. Each step eventually reqenqueues a packet in the LS_HDL_QUEUE that triggers the sccessuive step. Every incoming packet carries a command code (command_number) that has to be checked against the value of the global current_command_number to determine if the packet is relative to the last issued command. In case the two do not match the packed is simpli dropped and the block that it was carrying freed. The first step of every command is special since a standard sequence of actions needs to be carried out in this step. These actions are mainly constituted by the initialization of the static data needed by the command and are normally carried out in the function in charge of performing the first step. However two of these actions are carried out within the ls_hdl task. The first action is a call to function LS_activity_preparation(); this function stops any hs_hdl command that could be running, resets the HS subsystem and set the value of AID_spectroscopy to REQUIRINIG_HK in order to guarantee that the HK are properly acquired during the current ls command execution. The second action is a call to function ls_hdl_check_cmd_number(&cmd_in_queue) that simply checks again that the command just received is still the current one: even though this check was already performed it is a good idea to double check since function LS_activity_preparation() can stay in a wait state for 1 second and a new command could have been received during this time. */ //============================================================================== /*! \fn void ls_hdl (void) Implements task ls_hdl. The task is in wait state on the LS_HDL_QUEUE. Upon reception of the a packet in the queue the task does the following: - checks the field command_number of the queue message against the value of the global current_command_number to determine if the packet is relative to the last issued command. In case the two do not match the packed is simply dropped and the block that it was carrying freed. - makes a switch on the field operation_id of the queue message to determine what is the processing required and calls the appropriate functions */ //============================================================================== /*! \fn int ls_hdl_check_cmd_number (LS_HDL_MSG * msg) Checks whether the command carried by the message is obsolete or not. Returns 1 if obsolete, 0 if not. This function has to be called after the call to LS_activity_preparation(); in fact the latter could result in a task sleep of considerable length, so it's good to check if the arrival of a new TC has incremented the variable current_command_number; the block release must not be forgotten; the return value is 1 when the command is obsolete and so must be dropped */ //============================================================================== /*! \fn int void load_vector_scan (LS_HDL_MSG *msg) Executes the load_vector_scan command. Simply extracts the data contained in the TC command and store it in the appropriate static variable. After that the block used to store the TC is freed. */ //============================================================================== /*! \fn int start_vector_scan (LS_HDL_MSG *msg) First step of a vector scan or LO tuning command. It performs some consistency checks. It stores some data extracted with the received TC into appropriate globals (actually only the target current in case the command is a LO tuning). Eventually it enqueues towards the LS_HDL_QUEUE a packet that will trigger the successive step of the command. */ //============================================================================== /*! \fn int send_vector_scan_report (void) Prepares and sends the vector scan report. The data are stored in the vector vector_scan_data which is filled during the scan steps. The data are copied into a block extracted from the HK pool and the block is passed to tmtc_if by attching it to a message that is posted into the the HK_TM_QUEUE. */ //============================================================================== /*! \fn int lo_tune_find_best_step (int * step_index) Parse the vector scan data vector looking for the best match with the target value. The target current is stored in the global lo_tun_target_current, the current at the various step is the second last or the very last element of the data produced at every scan step (depending on whether the tuning is H or V) so that the current at step i is stored in vector_scan_data[i*VEC_SCAN_STEP_DATA_LEN-2+unit_under_tune] where unit_under_tune is 0 or 1 and selects the H or V current. Once the best step has been found the LO is driven into the best situation by issuing the commands that were issued in the best step. The index of the best step is returned by writing it into the address specified by the input parameter step_index. */ //============================================================================== /*! \fn int send_LO_tune_report (int best) This function is called both by a vector scan and by a LO tuning command. If argument best = 1 it is a LO command and the function finds the best step by calling function lo_tune_find_best_step(), drives the subsystem into the best configuration, prepares and sends the LO tune report which contains the vector scan data gathered in the best step. If argument best = 0 it is a vector scan. No best step is searched but a LO tuning report is produced anyway with the data of the last vector scan step. */ //============================================================================== /*! \fn int mkstep_vector_scan (LS_HDL_MSG *msg) Performs the generic step of a vector scan or LO tuning command which amounts to the following actions: After initial controls on the status of the LCU it checks if this is the last step or not. - If it is the last step, it sends the scan report the LO tuning report and returns. - If it is not the last step it 1) prepares vector command_pars[i] by adding to the initial values (stored in the lsb of HL_SET[i]) the step (stored in HL_STEP[i]) multiplied by the number of scan steps . 2) prepares vector of commands to be issued command_vector[i] by appending the parameters just computed to the command (stored in the msb HL_SET[i]) 3) Issues the commands just computed and stores the issued commands in vector vector_scan_data[] for reporting purposes. 4) Waits the specified wait time 5) Issues the 19 HK required at each step and stores the replays in vector_scan_data[] 6) Increases a global recording the number of vec scan steps alread executed 7) Eventually it enqueues a message towards the ls_hdl task that will trigger the next step. */ //============================================================================== /*! \fn int start_dip_scan_noif (LS_HDL_MSG * msg) Performs the starting phase of a diplexer scan without ifpower. The vector dip_scan_noif_data[] is used to store the data gathered in this and in the successive steps. After inital checks (fcu on etc) it extracts some data from the message that is passed as a paremeter and store it in appropriates globals (making a copy in dip_scan_noif_data for reporting purposes). After that it asks for mixer band hk values again storing the results into dip_scan_noif_data[]. Next it frees the block carried by the message and eventually posts a new message into the LS_HDL_QUEUE that will trigger the next step. */ //============================================================================== /*! \fn int mkstep_dip_scan_noif (LS_HDL_MSG * msg) Implements the generic step of a diplexer scan with no if power. Firstly it checks if the command is over (enough steps have been carried out). If yes a report is sent with tha data stored in dip_scan_noif_data. If it is not the last step it commands the diplexer position by sending a sequence of commands to ls, it wait the specified time, it asks for a sequence of GHK values storing the replies into the vector dip_scan_noif_data. Eventually it increases the glòobal counter storing the number of steps performed and finally it posts a message into the LS_HDL_QUEUE that will trigger the next step. */