demod.c

来自「QPSK Tuner details, for conexant chipset」· C语言 代码 · 共 1,683 行 · 第 1/5 页

C
1,683
字号
                     connection_limit = POLL_TIMEOUT;
                     trace_new((TRACE_LEVEL_3 | TRACE_DMD), "Poll.\n");
                  }
                  else
                  {
                     /* One of the bounces */
                     connection_limit = DEBOUNCE_TIMEOUT;
                     trace_new((TRACE_LEVEL_3 | TRACE_DMD), "Bounce.\n");
                  }

                  start_timer(glob_unit, connection_limit);
               }
            }
            break;
         case CALL_DISCONNECT:
            /* Call disconnect function */
            if (function_table[MY_MODULE(glob_unit)].disconnect(MY_UNIT(glob_unit)) == DEMOD_SUCCESS)
            {
               STATE_INFO(glob_unit).state = DISCONNECTED;
            }
            break;
         case DISCONNECTED:
            /* Do nothing */
            break;
         case INIT_SCAN:
            STATE_INFO(glob_unit).scanning = TRUE;
            STATE_INFO(glob_unit).state = CALL_CONNECT;
            /*STATE_INFO(glob_unit).scanning_spec = delete_me;*/
            STATE_INFO(glob_unit).tuning_spec = STATE_INFO(glob_unit).scanning_spec.current;
            break;
         default:
            /* Never get here - it's an array of enums. */
            break;
         }

         if (qu_receive(demod_queue, DEMOD_Q_TIMEOUT, msg) == RC_OK)
         {
            force_unit = msg[0] /*unit*/ + module_base_unit[msg[1]]; /*module*/
            STATE_INFO(force_unit).state = (STATE_LIST) msg[2];      /*state*/
         }
      }  /* endfor(all units) */
   }     /* endwhile(1) */

   task_terminate();
   return;
}

#undef STATE_INFO
#undef MY_MODULE
#undef MY_UNIT

/*****************************************************************************/
/*  FUNCTION:    change_demod_state                                          */
/*                                                                           */
/*  PARAMETERS:  unit & module number, and the state to change to.           */
/*                                                                           */
/*  DESCRIPTION:                                                             */
/*                                                                           */
/*  RETURNS:                                                                 */
/*                                                                           */
/*  CONTEXT:     May be called from any context, is designed as an interrupt */
/*               callback function.                                          */
/*                                                                           */
/*****************************************************************************/
static u_int32 change_demod_state(u_int32     unit,
                                  u_int32     module,
                                  STATE_LIST  state)
{
   u_int32  msg[4] = { 0 };
   msg[0] = unit;
   msg[1] = module;
   msg[2] = (u_int32) state;
   return(u_int32) (qu_send(demod_queue, msg));
}

static bool tuning_spec_equal(TUNING_SPEC ts1, TUNING_SPEC ts2)
{
   bool  bResult = FALSE;

   if (ts1.type == ts2.type)
   {
      switch (ts1.type)
      {
      case DEMOD_NIM_TERRESTRIAL:
         if (ts1.tune.nim_terrestrial_tune.Frequency == ts2.tune.
                nim_terrestrial_tune.Frequency)
         {
            bResult = TRUE;
         }
         break;

      default:
         trace_new((TRACE_LEVEL_3 | TRACE_DMD),
                   "Cannot check if we are already connected - tuning_spec_equal is not impemented for this tuning spec type (%d)\n",
                   ts1.type);
         break;
      }
   }

   return bResult;
}

u_int32 demod_lock_lost(u_int32 unit, u_int32 module)
{
   return(change_demod_state(unit, module, LOCK_LOST));
}

u_int32 demod_lock_found(u_int32 unit, u_int32 module)
{
   return(change_demod_state(unit, module, RE_ACQUIRE));
}

/*****************************************************************************/
/*  FUNCTION:    cnxt_demod_init                                             */
/*                                                                           */
/*  PARAMETERS:  number_units - pointer to an integer to be filled out with  */
/*                   the total number of units in this module.               */
/*                                                                           */
/*  DESCRIPTION: This function iterates through the demod_init table and     */
/*               initializes all the modules that have defined               */
/*               initialization functions there.  This function keeps track  */
/*               of the number of units each module initialization reports   */
/*               and returns a count of units in the system.                 */
/*                                                                           */
/*  RETURNS:     DEMOD_INITIALIZED - the system has already been             */
/*                   initialized.                                            */
/*               DEMOD_MODULE_COUNT - there are more initialization          */
/*                   functions in the demod_init table than local data       */
/*                   structures can accomodate.  Expand the structures.      */
/*               DEMOD_BAD_FTABLE - a module did not correctly fill out the  */
/*                   interface function table.                               */
/*               DEMOD_BAD_UNIT - a module reported successful               */
/*                   initialization but a bad number of units in the module. */
/*               DEMOD_UNIT_COUNT - there are more units in the component    */
/*                   modules than local data structures can accomodate.      */
/*                   Expand the structures.                                  */
/*               DEMOD_SUCCESS - the function completed successfully.        */
/*               The error indication from a module initialization routine.  */
/*                                                                           */
/*  CONTEXT:     Must be called from a non-interrupt context.                */
/*                                                                           */
/*****************************************************************************/
DEMOD_STATUS cnxt_demod_init(u_int32 *number_units)
{
   u_int32        number_demod_slots, number_demod_modules;
   u_int32        ii, jj, unit_count, current_base_unit = 0;
   DEMOD_STATUS   ret_val;
   bool           need_task = FALSE;
   u_int32        module_unit_count[MAX_MODULES], current_module, *ptr;

   if (!number_units)
   {
      return DEMOD_BAD_PARAMETER;
   }

   if (demod_initialized)
   {
      return DEMOD_INITIALIZED;
   }
   else
   {
      demod_initialized = 1;
   }

   /* how many drivers to initialize? */
   number_demod_slots = sizeof(demod_init) / sizeof(INIT_FUNC *);
   number_demod_modules = 0;
   for (ii = 0; ii < number_demod_slots; ++ii)
   {
      if (demod_init[ii])
      {
         ++number_demod_modules;
      }
   }

   if (number_demod_modules > MAX_MODULES)
   {
      return DEMOD_MODULE_COUNT;
   }

   /* initialize the modules */
   current_module = 0;
   for (ii = 0; ii < number_demod_slots; ++ii)
   {
      if (demod_init[ii])
      {
         unit_count = 0;
         ret_val = demod_init[ii](current_module, &unit_count, &function_table[current_module]);

         /* Check for the special case of no hardware present for the demod.
            A return of DEMOD_NO_HARDWARE means to continue initialization and
            allows autoconfiguration of interfaces. */
         if (ret_val != DEMOD_NO_HARDWARE)
         {
            if (ret_val != DEMOD_SUCCESS)
            {
               /* fatal error on initialization */
               return ret_val;
            }
            else
            {
               if (unit_count)
               {
                  module_unit_count[current_module] = unit_count;
                  module_base_unit[current_module] = current_base_unit;
                  current_base_unit += unit_count;
                  if (!function_table[current_module].unit_type ||
                      !function_table[current_module].ioctl ||
                      !function_table[current_module].connect ||
                      !function_table[current_module].disconnect ||
                      (
                         (
                            !function_table[current_module].get_tuning ||
                            !function_table[current_module].set_callback ||
                            !function_table[current_module].clear_callback
                         ) && !function_table[current_module].scan_next
                      ) ||
                      !function_table[current_module].get_signal ||
                      !function_table[current_module].get_lock)
                  {
                     /* did not fill out the function table correctly */
                     return DEMOD_BAD_FTABLE;
                  }
               }
               else
               {
                  /* why a successful init with no units? */
                  return DEMOD_BAD_UNIT;
               }

               ++current_module;
            }
         }
         else
         {
            --number_demod_modules;
         }
      }
   }

   *number_units = total_number_units = current_base_unit;
   if (total_number_units > MAX_UNITS)
   {
      return DEMOD_UNIT_COUNT;
   }

   /* initialize the unit translation table */
   memset(unit_xlat_table, 0, sizeof(unit_xlat_table));
   ptr = unit_xlat_table;
   for (ii = 0; ii < number_demod_modules; ++ii)
   {
      for (jj = 0; jj < module_unit_count[ii]; ++jj)
      {
         *ptr++ = ii;
      }
   }

   /* Create the state machine task */
   need_task = FALSE;
   for (ii = 0; ((ii < number_demod_modules) && (need_task == FALSE)); ++ii)
   {
      if (function_table[ii].scan_next)
      {
         need_task = TRUE;
      }
   }

   if (need_task == TRUE)
   {
      demod_queue = qu_create(10, "DMQU");
      task_create(&StateTask,
                  (void *)NULL,
                  (void *)NULL,
                  DMOD_TASK_STACK_SIZE,
                  DMOD_TASK_PRIORITY,
                  DMOD_TASK_NAME);
   }

   /* initialize the local callback table */
   memset(callback_table, 0, sizeof(callback_table));

   /* initialize the open flag table */
   memset(open_flag, 0, sizeof(open_flag));

   return DEMOD_SUCCESS;
}

/*****************************************************************************/
/*  FUNCTION:    cnxt_demod_get_number_of_units                              */
/*                                                                           */
/*  PARAMETERS:  number_units - pointer to the variable to be set with the   */
/*                   number of units available in the system.                */
/*                                                                           */
/*  DESCRIPTION: This function returns the count of units present in the     */
/*               system.                                                     */
/*                                                                           */
/*  RETURNS:     DEMOD_UNINITIALIZED - this module has not been initialized. */
/*               DEMOD_SUCCESS - the function completed successfully.        */
/*                                                                           */
/*  CONTEXT:     Must be called from a non-interrupt context.                */
/*                                                                           */
/*****************************************************************************/
DEMOD_STATUS cnxt_demod_get_number_of_units(u_int32 *number_units)
{
   if (!demod_initialized)
   {
      return DEMOD_UNINITIALIZED;
   }

   if (!number_units)
   {
      return DEMOD_BAD_PARAMETER;
   }

   *number_units = total_number_units;
   return DEMOD_SUCCESS;
}

/*****************************************************************************/
/*  FUNCTION:    cnxt_demod_get_unit_type                                    */
/*                                                                           */
/*  PARAMETERS:  unit - the unit number for which type information is        */
/*                   requested.                                              */
/*               unit_type - pointer to the DEMOD_NIM_TYPE variable to be    */
/*                   filled out.                                             */
/*                                                                           */
/*  DESCRIPTION: This function gathers information about the type of the     */
/*               unit that is the subject of the request by calling the      */
/*               appropriate module function to supply the information.      */
/*                                                                           */
/*  RETURNS:     DEMOD_UNINITIALIZED - this module has not been initialized. */
/*               DEMOD_BAD_UNIT - the unit number is not valid.              */
/*               The return value from the called module function.           */
/*                                                                           */
/*  CONTEXT:     Must be called from a non-interrupt context.                */
/*                                                                           */
/*****************************************************************************/

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?