/* **********************************************************************
 * *                                                                    *
 * *    Shared Custom Encode/Decode Routines for RVP8 and DSP Driver    *
 * *                                                                    *
 * **********************************************************************
 * File: libs/user/dspcustom.c
 *
 *                        COPYRIGHT (c) 2004  BY
 *          SIGMET INCORPORATED, WESTFORD MASSACHUSETTS, U.S.A.
 * 
 * THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED AND  COPIED
 * ONLY  IN  ACCORDANCE WITH  THE  TERMS  OF  SUCH  LICENSE  AND WITH THE
 * INCLUSION OF THE ABOVE COPYRIGHT NOTICE.  THIS SOFTWARE  OR  ANY OTHER
 * COPIES  THEREOF MAY NOT BE PROVIDED OR OTHERWISE MADE AVAILABLE TO ANY
 * OTHER PERSON.  NO TITLE TO AND OWNERSHIP OF  THE  SOFTWARE  IS  HEREBY
 * TRANSFERED.
 */
#include <stdio.h>
#include <string.h>
#include <math.h>

#include "sigtypes.h"
#include "dsp.h"
#include "rvp8.h"
#include "user_lib.h"

/* This collection of routines are shared between the DSP driver and
 * the RVP8/Main threads.  Since the latter can not link directly to
 * the DSP driver, we put these routines here.
 */

/* *************************************
 * *                                   *
 * *  BATCH Major Mode Command Coding  *
 * *                                   *
 * *************************************
 */

/* The BATCH major mode 16-bit I/O has the following format in both
 * directions:
 *
 *  ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___
 * |   |   |Set|Get| 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | Opcode
 *  --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
 *  ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___
 * |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |AVL| Input-1
 *  --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
 *  ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___
 * |            Low PRF Scale, 10000 * Unsigned Value              | Input-2
 *  --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
 *  ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___
 * |             Low PRF Offset, 100 * Unsigned Hertz              | Input-3
 *  --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
 *  ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___
 * |          Low Samples Scale, 10000 * Unsigned Value            | Input-4
 *  --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
 *  ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___
 * |          Low Samples Offset, 100 * Unsigned Samples           | Input-5
 *  --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
 *  ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___
 * |       Maximum Unfolding Range, 20 * Unsigned Kilometers       | Input-6
 *  --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
 *  ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___
 * |       Low PRF Samples to Average on Each Side of Center       | Input-7
 *  --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
 *  ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___
 * |     Power Difference Threshold for Reflectivity, 100 * dB     | Input-8
 *  --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
 *  ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___
 * |       Power Difference Threshold for Velocity, 100 * dB       | Input-9
 *  --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
 *  ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___
 * |        Power Difference Threshold for Width, 100 * dB         | Input-10
 *  --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
 *  ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___
 * |     Amount to increase low PRF noise threshold, 100 * dB      | Input-11
 *  --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
 */

/* ------------------------------
 * Decode an array of UINT2 values to produce a BATCH setup structure
 * in native form.
 */
void rvp8DecodeBatchOpcode
( volatile struct rvp8BatchSetup *pUser_a,
  const UINT2 args_a[], SINT4 nArgs_a )
{
  memset( (void *)pUser_a, 0, sizeof(struct rvp8BatchSetup) ) ;
  if( nArgs_a >  0 ) pUser_a->lAvailable    =      ( args_a[ 0] & 1 ) ;
  if( nArgs_a >  1 ) pUser_a->fLoPrfScl     = ((FLT4)args_a[ 1]) / 10000.0 ;
  if( nArgs_a >  2 ) pUser_a->fLoPrfOff     = ((FLT4)args_a[ 2]) /   100.0 ;
  if( nArgs_a >  3 ) pUser_a->fSampsScl     = ((FLT4)args_a[ 3]) / 10000.0 ;
  if( nArgs_a >  4 ) pUser_a->fSampsOff     = ((FLT4)args_a[ 4]) /   100.0 ;
  if( nArgs_a >  5 ) pUser_a->fMaxUnfoldKM  = ((FLT4)args_a[ 5]) /    20.0 ;
  if( nArgs_a >  6 ) pUser_a->iLoPrfAvgSide =        args_a[ 6] ;
  if( nArgs_a >  7 ) pUser_a->fdBOverRefl   = ((FLT4)args_a[ 7]) /   100.0 ;
  if( nArgs_a >  8 ) pUser_a->fdBOverVel    = ((FLT4)args_a[ 8]) /   100.0 ;
  if( nArgs_a >  9 ) pUser_a->fdBOverWid    = ((FLT4)args_a[ 9]) /   100.0 ;
  if( nArgs_a > 10 ) pUser_a->fdBAddNseThr  = ((FLT4)args_a[10]) /   100.0 ;
}

/* ------------------------------
 * Decode a BATCH setup structure in native form to produce an array
 * of UINT2 values.
 */
SINT4 rvp8EncodeBatchOpcode
( volatile const struct rvp8BatchSetup *pUser_a,
  UINT2 args_a[ BATCHOPARGLENGTH ] )
{
  args_a[ 0] = pUser_a->lAvailable ? 1 : 0 ;
  args_a[ 1] = NINT( 10000.0 * pUser_a->fLoPrfScl    ) ;
  args_a[ 2] = NINT(   100.0 * pUser_a->fLoPrfOff    ) ;
  args_a[ 3] = NINT( 10000.0 * pUser_a->fSampsScl    ) ;
  args_a[ 4] = NINT(   100.0 * pUser_a->fSampsOff    ) ;
  args_a[ 5] = NINT(    20.0 * pUser_a->fMaxUnfoldKM ) ;
  args_a[ 6] = pUser_a->iLoPrfAvgSide ;
  args_a[ 7] = NINT(   100.0 * pUser_a->fdBOverRefl  ) ;
  args_a[ 8] = NINT(   100.0 * pUser_a->fdBOverVel   ) ;
  args_a[ 9] = NINT(   100.0 * pUser_a->fdBOverWid   ) ;
  args_a[10] = NINT(   100.0 * pUser_a->fdBAddNseThr ) ;

  return( BATCHOPARGLENGTH ) ;

#if BATCHOPARGLENGTH != 11
#error Please manually maintain BATCH Encode/Decode routines
#endif
}

/* *************************************
 * *                                   *
 * *  Miscellaneous RVP8 Translations  *
 * *                                   *
 * *************************************
 */
/* ------------------------------
 * Convert RVP8 filter specification structure From/To 16-bit I/O
 * units.
 */
void rvp8DecodeSpecFilt
( volatile struct rvp8SpecFilt *pUser_a,
  volatile const struct rvp8SpecFiltIO *pCode_a )
{
  memset( (void *)pUser_a, 0, sizeof(struct rvp8SpecFilt) ) ;
  pUser_a->iType        = pCode_a->iType ;
  pUser_a->iMinWidth    = pCode_a->iMinWidth ;
  pUser_a->iSlopePts    = pCode_a->iSlopePts ;
  pUser_a->iEdgePts     = pCode_a->iEdgePts ;
  pUser_a->fClutWidthMS = 1E-3 * (FLT4)pCode_a->iClutWidthMMS ;
  pUser_a->iWinType     = pCode_a->iWinType ;
}

void rvp8EncodeSpecFilt
( volatile struct rvp8SpecFiltIO *pCode_a,
  volatile const struct rvp8SpecFilt *pUser_a )
{
  memset( (void *)pCode_a, 0, sizeof(struct rvp8SpecFiltIO) ) ;
  pCode_a->iType         = pUser_a->iType ;
  pCode_a->iMinWidth     = pUser_a->iMinWidth ;
  pCode_a->iSlopePts     = pUser_a->iSlopePts ;
  pCode_a->iEdgePts      = pUser_a->iEdgePts ;
  pCode_a->iClutWidthMMS = NINT( 1E3 * pUser_a->fClutWidthMS ) ;
  pCode_a->iWinType      = pUser_a->iWinType ;
}
