// to add the TS fifo and pool description //================================================================================================ /*! \file hs0.c \brief It takes data out of the HW fifos, organises it into frames and passes them to hs1. The mechanism for emptying the fifos is the following: as soon as a fifo becomes half full a HW interrupt is generated and the ISR raises the event HS0_EVENT. The task hs0 is waiting for this event and, when it is waked up, it transfers a segment of data from the half full fifo to the board memory. With the mechanism described above, the last data of a measurement are not transferred since it is possible that the data are not enough to raise the half full interrupt. For this reason, when a module performing measurements (the VM and other procedures) issues the last data transfer to a fifo, it also raises a virtuoso event named HS_FLUSH_EVENT. A task called hs_flush is waiting for this event and is in charge of emptying the fifos, thus completing the data transfer. The data are read from the fifos in segments (or blocks) whose size depends on the instrument (WBS or HRS) they belong to: the dimensions are called WBS_BLOCK_DIM, HRS_BLOCK_DIM. We want the block dimensions to meet the following conditions: block_dim < half_fifo 2*block_dim > half_fifo block_dim must be a submultiple of the frame dimension Remember that the frame dimension is 8210 for WBS and 4160 for HRS. According to the previous conditions, and given that half_fifo is 2048 in AVM1, the best choice for the block dimensions is: WBS_BLOCK_DIM 1642 HRS_BLOCK_DIM 1040 The segments read from the fifos are stored into memory blocks obtained from two hifi_pools: HRS_FRAME_POOL and WBS_FRAME_POOL. These memory blocks are as big as a full instrument frame, so they are gradually filled by incoming segments (a HRS pool block needs 4 segments to fill up, while a WBS pool block needs 5). The pool block number and a pointer to the block data are stored in the following common variables: static int xxx_x_block; static int* p_xxx_x_block; In addition the variables: static int xxx_x_nread; store the number of data segments already put into a pool block: they are used to see when a pool block is full and then needs to be passed to hs1. Both hs0 and hs_flush perform two main steps. Firstly, they scan the four HW fifos, in order to detect which one is half full (hs0) or not empty (hs_flush): when data are found in a fifo, a segment is moved to the corresponding pool block. Secondly, the two tasks check (through the variables xxx_x_nread) whether any pool block is full (i.e. contains a whole instrument frame) and if they find a full block they pass it to hs1 by sending a message in the frame queue with the block number. As soon as a frame is delivered to hs1, a new block is requested to the same hifi_pool, so that a block is always available for each fifo. Note: for use on AVM2, where half_fifo is 8192, just a few changes are needed. In order to satisfy the previous three requirements, the block dimensions should be chosen as follows: WBS_BLOCK_DIM 4105 HRS_BLOCK_DIM 4160 Moreover, in this case two less blocks need to be allocated to each of the frame pools HRS_FRAME_POOL, WBS_FRAME_POOL. This involves making a change to the file hifi_pool.h, where HRS_FRAME_POOL_BLOCK_NR and WBS_FRAME_POOL_BLOCK_NR should be turned to 4 (2 blocks per fifo are enough in AVM2, while at least 3 blocks per fifo are required in AVM1). This change also allows us to reduce by approximately 8000 (exadecimal notation) the memory reserved to the seg_dmda segment (see the hifi.ach file). */ //================================================================================================ /*! \fn void hs0( void ) This function implements Virtuoso task hs0. It calls the function hs_init and then waits until HS_EVENT indicates a half full interrupt. When triggered by HS_EVENT, hs0 scans the four fifos (by calling the function get_fifo) and reads a segment of SD data from the fifo that is half full. At the end it checks if any of the frames is ready and in this case delivers the frame (by calling deliver_frame). */ //================================================================================================ /*! \fn void hs_flush( void ) This function implements Virtuoso task hs_flush. It is activated by the HS_FLUSH_EVENT. It scans the four fifos (by calling the function flush_fifo) and reads a segment of SD data if the fifo is non empy. At the end it checks if any of the frame is ready and in this case delivers the frame (by calling deliver_frame). */ //================================================================================================ /*! \fn void hs_init (void) This function is used to initialize the hs0 module. For each of the four FIFOs it gets a block of memory from the appropriate pool (HRS_FRAME _POOL or WBS_FRAME_POOL); then it sets to zero the number of data segments read for all the pools. */ //================================================================================================ /*! \fn void deliver_frame (int fifo_id, int *pblock_nr, int **pdata) This function sends a message to hs1 by means of the FRAME_QUEUE. The message holds the fifo_id and block number of the pool where the frame is stored. After sending the message a new block is allocated from hifi_pool. */ //================================================================================================ /*! \fn void get_fifo (int fifo_id, int *pdata, int *nread, unsigned int iv_mask, unsigned int hf_mask, unsigned int subsys_mask, unsigned int read_block_dim) This functions checks whether the fifo is half full. If yes, reads a segment of data into the corresponding block and increases the number of segments read for that fifo. */ //================================================================================================ /*! \fn void flush_fifo (int fifo_id, int *pdata, int *nread, unsigned int iv_mask, unsigned int hf_mask, unsigned int subsys_mask, unsigned int read_block_dim) This functions checks whether the fifo is non empty. If non empty, reads a segment of data into the corresponding block and increase the number of segment read for that fifo. */ //================================================================================================ /*! \fn void hs_reset (void) This function resets the hs0 module. It simply sets the number of data segments read to zero for all the pools. */