demod.c

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

C
1,683
字号
{
   debounce_status_array[unit] = -1;
   return;
}

#define TIMER_RES 10/* Go down 10 ms at a time */

static void clock_func(timer_id_t id, void *pUserData)
{
   u_int32  i;
   for (i = 0; i < total_number_units; i++)
   {
      if (unit_timer[i].connection_timer > 0)
      {
         unit_timer[i].connection_timer -= TIMER_RES;
         if (unit_timer[i].connection_timer <= 0)
         {
            unit_timer[i].flag = TRUE;
         }
      }
   }
}

static bool check_timer(u_int32 unit)
{
   bool  retval;
   if (unit_timer[unit].flag == TRUE)
   {
      retval = TRUE;
      unit_timer[unit].flag = FALSE;
   }
   else
   {
      retval = FALSE;
   }

   return(retval);
}

static void start_timer(u_int32 unit, int timeout)
{
   unit_timer[unit].flag = FALSE;
   unit_timer[unit].connection_timer = timeout;
   return;
}

static void StateTask(void *parm)
{
   int32             glob_unit, force_unit = (-1), saved_unit = (-1);
   u_int32           connection_limit;
   bool              retval;
   DEBOUNCE_STATUS   debounce_status;
   tick_id_t         tick_id;
   u_int32           msg[4];
   /*SCAN_SPEC         delete_me;*/
   TUNING_SPEC       retune;

   #if 0
   #define SCAN_FREQ ((u_int32) 738000000)
   delete_me.type = DEMOD_NIM_TERRESTRIAL;
   delete_me.current.tune.nim_terrestrial_tune.Frequency = SCAN_FREQ;
   delete_me.current.tune.nim_terrestrial_tune.Frame = FRAME_AUTO;
   delete_me.current.tune.nim_terrestrial_tune.InputBW = BANDWIDTH_8_MHZ;
   delete_me.scan.stop = delete_me.current;
   delete_me.scan.stop.tune.nim_terrestrial_tune.Frequency = SCAN_FREQ + (u_int32) 16000000;
   #endif
   if ((tick_id = tick_create((PFNTIMERC) clock_func, (void *)0, "DEMD")) == 0)
   {
      trace_new((TRACE_LEVEL_3 | TRACE_DMD),
                "Can't hook the tick incrementer in.\n");
   }
   else
   {
      if (tick_set(tick_id, (u_int32) TIMER_RES, FALSE) != RC_OK)
      {
         trace_new((TRACE_LEVEL_3 | TRACE_DMD),
                   "Error setting demod tick timer.\n");
      }

      if (tick_start(tick_id) != RC_OK)
      {
         trace_new((TRACE_LEVEL_3 | TRACE_DMD),
                   "Error starting demod tick timer.\n");
      }
   }

   for (glob_unit = 0; glob_unit < (int32) total_number_units; glob_unit++)
   {
      STATE_INFO(glob_unit).state = DISCONNECTED;
      STATE_INFO(glob_unit).scanning = FALSE;
      unit_timer[glob_unit].flag = FALSE;
      unit_timer[glob_unit].connection_timer = -1;
   }

   while (1)
   {
      for (glob_unit = 0; glob_unit < (int32) total_number_units; glob_unit++)
      {
         #define VALID_UNIT(X)   ((X >= 0) && (X < (int32) total_number_units))
         if (VALID_UNIT(force_unit))
         {
            if (!(VALID_UNIT(saved_unit)))
            {
               saved_unit = glob_unit;
            }

            glob_unit = force_unit;
         }
         else if (VALID_UNIT(saved_unit))
         {
            glob_unit = saved_unit;
            saved_unit = -1;
         }

         force_unit = -1;
         if ((void *)(function_table[MY_MODULE(glob_unit)].scan_next) == NULL)
         {
            continue;
         }

         switch (STATE_INFO(glob_unit).state)
         {
         case CALL_CONNECT:
            /* Call connect with new params */
            if (function_table[MY_MODULE(glob_unit)].connect(MY_UNIT(glob_unit),
                                                             &(STATE_INFO(glob_unit).tuning_spec),
                                                             &connection_limit) != DEMOD_SUCCESS)
            {
               STATE_INFO(glob_unit).state = DISCONNECTED;
               call_back(glob_unit,
                         DEMOD_CONNECT_STATUS,
                         DEMOD_ABORTED,
                         &(STATE_INFO(glob_unit).tuning_spec));
               trace_new((TRACE_LEVEL_3 | TRACE_DMD),
                         "Callback, connect failure\n");
               break;
            }
            else
            {
               start_timer(glob_unit, (int)connection_limit);
               STATE_INFO(glob_unit).state = ACQUIRING_SIGNAL;
               /* FALLTHROUGH */
            }

         /* POSSIBLE FALLTHROUGH */
         case ACQUIRING_SIGNAL:
            /* Check for lock status & conditionally do callback */
            function_table[(MY_MODULE(glob_unit))].get_lock(MY_UNIT(glob_unit),
                                                            &retval);
            if (retval == FALSE)
            {
               trace_new((TRACE_LEVEL_3 | TRACE_DMD),
                         "acq%l",
                         (long)STATE_INFO(glob_unit).tuning_spec.tune.nim_terrestrial_tune.Frequency);
               if (check_timer(glob_unit))
               {
                  /* This 'Acquire' has failed */
                  trace_new((TRACE_LEVEL_3 | TRACE_DMD), "Acquire fail\n");
                  if (STATE_INFO(glob_unit).scanning == TRUE)
                  {
                     STATE_INFO(glob_unit).state = SCAN_NEXT;
                  }
                  else
                  {
                     /* Set to poll forever */
                     STATE_INFO(glob_unit).state = LOCK_LOST;
                     call_back(glob_unit,
                               DEMOD_CONNECT_STATUS,
                               DEMOD_FAILED,
                               (TUNING_SPEC *)NULL);
                     trace_new((TRACE_LEVEL_3 | TRACE_DMD),
                               "Callback, acquire fail\n");
                  }
               }
               else
               {
                  /* If we have neither got a lock nor timed out...   */
                  /*    ...continue to acquire, i.e. do nothing here. */
               }
               break;
            }
            else
            {
               /* We have got a signal. We shall see if we need to re-tune */
               /* to the frequency we've got. FALL THROUGH to RE_ACQUIRE   */
               trace_new((TRACE_LEVEL_3 | TRACE_DMD),
                         "We've got a lock, deciding on re-acquire next.\n");
               trace_new((TRACE_LEVEL_3 | TRACE_DMD), "Acquire succeed\n");
            }

         /* FALL THROUGH */
         case RE_ACQUIRE:
            /* Set array member tuning spec to actual tuning param */
            /* This value can then be used for re-acquisition...   */
            /* either now (to fine-tune) or in case of signal fail */
            trace_new((TRACE_LEVEL_3 | TRACE_DMD),
                      "Deciding whether to re-acquire.\n");
            if (((function_table[MY_MODULE(glob_unit)].get_tuning) != NULL) &&
                (STATE_INFO(glob_unit).scanning != TRUE))
            {
               function_table[MY_MODULE(glob_unit)].get_tuning(MY_UNIT(glob_unit),
                                                               &retune);
               STATE_INFO(glob_unit).tuning_spec = retune;
            }

            /* Go to optional re-acquire if exists and is not scanning */
            if (((function_table[MY_MODULE(glob_unit)].re_acquire) != NULL) &&
                (STATE_INFO(glob_unit).scanning != TRUE))
            {
               retval = function_table[MY_MODULE(glob_unit)].re_acquire(&(STATE_INFO(glob_unit).tuning_spec),
                                                                        &retune);
            }
            else
            {
               retval = FALSE;
            }

            if (retval == TRUE)
            {
               /* The actual tune is too far away - retune */
               trace_new((TRACE_LEVEL_3 | TRACE_DMD),
                         "Re-acquire is on - going to call_connect.\n");
               STATE_INFO(glob_unit).state = CALL_CONNECT;
               break;
            }
            else
            {
               trace_new((TRACE_LEVEL_3 | TRACE_DMD),
                         "Re-acquire unnecessary or no re_acquire fn.\n");
               STATE_INFO(glob_unit).state = CONNECTED;
               start_timer(glob_unit, POLL_TIMEOUT);
               /* Callback - Acquire Succeed */
               if (STATE_INFO(glob_unit).scanning == TRUE)
               {
                  call_back(glob_unit,
                            DEMOD_SCAN_STATUS,
                            DEMOD_SCAN_COMPLETE,
                            &retune);
                  trace_new((TRACE_LEVEL_3 | TRACE_DMD),
                            "Callback, scan succeed\n");
                  STATE_INFO(glob_unit).scanning = FALSE;
               }
               else
               {
                  call_back(glob_unit,
                            DEMOD_CONNECT_STATUS,
                            DEMOD_CONNECTED,
                            &retune);
                  trace_new((TRACE_LEVEL_3 | TRACE_DMD),
                            "Callback, acquire succeed\n");
               }
            }
            break;
         case SCAN_NEXT:
            retval = function_table[MY_MODULE(glob_unit)].scan_next(MY_UNIT(glob_unit),
                                                                    &(STATE_INFO(glob_unit).scanning_spec));
            STATE_INFO(glob_unit).tuning_spec = STATE_INFO(glob_unit).scanning_spec.current;
            if (retval == TRUE)
            {
               /* True implies come to end of allowed scanning range... */
               /* WITHOUT getting a lock! */
               call_back(glob_unit,
                         DEMOD_SCAN_STATUS,
                         DEMOD_SCAN_NO_SIGNAL,
                         (TUNING_SPEC *)NULL);
               trace_new((TRACE_LEVEL_3 | TRACE_DMD), "Callback, scan fail\n");
               STATE_INFO(glob_unit).scanning = FALSE;
               STATE_INFO(glob_unit).state = DISCONNECTED;
            }
            else
            {
               STATE_INFO(glob_unit).state = CALL_CONNECT;
            }
            break;
         case CONNECTED:
            /* Check the signal is still there */
            if (check_timer(glob_unit))
            {
               function_table[MY_MODULE(glob_unit)].get_lock(MY_UNIT(glob_unit),
                                                             &retval);
               if (retval == TRUE)
               {
                  start_timer(glob_unit, POLL_TIMEOUT);
                  break;
               }

               /* else FALLTHROUGH */
            }
            else
            {
               break;
            }

         case LOCK_LOST:
            set_debounce(glob_unit);
         /* set_debounce ensures next get_debounce will be JUST_LOST */
         /* FALLTHROUGH */
         case LOCK_WANTED:
            if ((STATE_INFO(glob_unit).state != LOCK_WANTED) ||
                (check_timer(glob_unit)))
            {
               STATE_INFO(glob_unit).state = LOCK_WANTED;   /* for fallthrough */
               /* poll forever to see if the signal returns */
               function_table[MY_MODULE(glob_unit)].get_lock(MY_UNIT(glob_unit),
                                                             &retval);
               if (retval == TRUE)
               {
                  /* We've got a lock back but we don't know how */
                  /* See if re-tuning would be helpful           */
                  trace_new((TRACE_LEVEL_3 | TRACE_DMD),
                            "Poll has been successful. Forcing state to re-acquire.\n");
                  STATE_INFO(glob_unit).state = RE_ACQUIRE;
                  force_unit = glob_unit;             /* Go around again */
               }
               else
               {
                  if (debounce_time == 0)
                  {
                     un_debounce(glob_unit);
                     /* This makes sure it won't bounce at all */
                  }

                  debounce_status = get_debounce(glob_unit);
                  if (debounce_status == BOUNCED_OUT)
                  {
                     /* One-time given up bouncing, start steady poll */
                     connection_limit = POLL_TIMEOUT; /* Now we're polling */
                     trace_new((TRACE_LEVEL_3 | TRACE_DMD),
                               "Callback signal lost & start polling.\n");
                     call_back(glob_unit,
                               DEMOD_CONNECT_STATUS,
                               DEMOD_DRIVER_LOST_SIGNAL,
                               (TUNING_SPEC *)NULL);
                  }
                  else if (debounce_status == LOCKED_OUT)
                  {
                     /* Steady state polling, longer timeout */

⌨️ 快捷键说明

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