Integrator Resources

The official home for NAI Support

Not sure where to start? Try Quick Start Guide or ask a question below!

Toggle Components with Visual Button
JavaScript Form Processing

SER BIT

SER BIT Sample Application (SSK 2.x)

Overview

The SER BIT sample application demonstrates how to run a Built-In Test (BIT) on a serial module using the NAI Software Support Kit (SSK 2.x). The application disables the selected channel (and its pair channel on modules that require it), initiates the BIT, waits for the result, and reports whether the test passed or failed. After the test, the channel’s original enable state is restored.

BIT is a hardware self-test that verifies the serial channel is functioning correctly. It exercises the internal data paths of the channel without requiring any external cabling. This sample supports SER module types including SC3, SCB, CMR, CMH, and IF3.

For the SSK 1.x version, see SER BIT (SSK 1.x).

Prerequisites

Before running this sample, make sure you have:

  • An NAI board with a SER module installed (SC3, SCB, CMR, CMH, IF3, or compatible).

  • SSK 2.x installed on your development host.

  • The sample applications built. Refer to the SSK 2.x Software Development Guide for platform-specific build instructions.

How to Run

Launch the ser_bit executable from your build output directory. On startup the application looks for a configuration file (default_SER_BIT.txt). Once connected, the application queries for a channel and runs the BIT. The test can be repeated by pressing Enter.

Board Connection and Module Selection

Note
This startup sequence is common to all NAI sample applications. The board connection and module selection code shown here is not specific to SER.

The main() function follows a standard SSK 2.x startup flow:

  1. Call naiapp_RunBoardMenu() to load a saved configuration file or present the interactive board menu.

  2. Query the user for a card index and module slot.

  3. Retrieve the module ID with naibrd_GetModuleName().

  4. Call Run_SER_BIT(cardIndex, module, moduleID).

#ifdef NAIBSP_CONFIG_SOFTWARE_OS_VXWORKS
int32_t SER_BIT_Sample(void)
#else
int32_t main(void)
#endif
{
   bool_t stop = NAI_FALSE;
   int32_t cardIndex;
   int32_t moduleCnt;
   int32_t module;
   uint32_t moduleID = 0;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

   if (naiapp_RunBoardMenu(CONFIG_FILE) == NAI_TRUE)
   {
      while (stop != NAI_TRUE)
      {
         stop = naiapp_query_CardIndex(naiapp_GetBoardCnt(), 0, &cardIndex);
         if (stop != NAI_TRUE)
         {
            check_status(naibrd_GetModuleCount(cardIndex, &moduleCnt));
            stop = naiapp_query_ModuleNumber(moduleCnt, 1, &module);
            if (stop != NAI_TRUE)
            {
               check_status(naibrd_GetModuleName(cardIndex, module, &moduleID));
               if ((moduleID != 0))
               {
                  Run_SER_BIT(cardIndex, module, moduleID);
               }
            }
         }

         naiif_printf("\r\nType Q to quit or Enter key to restart application:\r\n");
         stop = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
      }
   }

   naiif_printf("\r\nType the Enter key to exit the program: ");
   naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
   naiapp_access_CloseAllOpenCards();

   return 0;
}
Important

Common connection errors you may encounter at this stage:

  • No board found — verify that the board is powered on and physically connected.

  • Connection timeout — confirm network settings or bus configuration.

  • Module not present at selected slot — verify which slots are populated using the board menu.

Program Structure

Entry Point

The entry point is main() on most platforms, or SER_BIT_Sample() on VxWorks.

Application Flow

  1. Query for a channel number.

  2. Save the channel’s current enable state.

  3. Disable the channel (and its pair channel if required).

  4. Initiate BIT and wait for the result.

  5. Report pass/fail.

  6. Restore the channel’s original enable state.

  7. Prompt to repeat or quit.

Channel Disable for BIT

BIT requires that the selected channel be disabled. On certain module types, channels must be disabled in pairs:

/* Get the state of the channel before BIT is executed.*/
check_status(naibrd_SER_GetChannelEnable(cardIndex, module, chanNum, &enable));

/* Disable the channel. Channels MUST be disabled for BIT to run. */
check_status(naibrd_SER_SetChannelEnable(cardIndex, module, chanNum, NAI_FALSE));

/* For BIT to run on the SC3 we need to make sure the channels are disabled in pairs (1&2, 2&3, etc.) */
if (moduleID == NAIBRD_MODULE_ID_SC3 || moduleID == NAIBRD_MODULE_ID_SCB || moduleID == NAIBRD_MODULE_ID_CMR || moduleID == NAIBRD_MODULE_ID_IF3)
{
   if ((chanNum % 2) == 0)   /* Even channel */
      check_status(naibrd_SER_SetChannelEnable(cardIndex, module, (chanNum - 1), NAI_FALSE));
   else
      check_status(naibrd_SER_SetChannelEnable(cardIndex, module, (chanNum + 1), NAI_FALSE));
}

For the CMH module, only 5 channels are available and channel 5 has no pair, so the pair disable is skipped for channel 5.

Running the BIT

The application initiates BIT with NAIBRD_SER_INITIATE_BIT_WAIT_RESULT, which blocks until the test completes:

status = naibrd_SER_InitiateBIT(cardIndex, module, chanNum, NAIBRD_SER_INITIATE_BIT_WAIT_RESULT);

if ( NAI_SUCCESS == status )
   naiif_printf("BIT Passed.\r\n");
else
   check_status(status);

If the BIT passes, NAI_SUCCESS is returned. Otherwise, the error status is printed. After the test, the channel’s original enable state is restored:

check_status(naibrd_SER_SetChannelEnable(cardIndex, module, chanNum, enable));

Alternatively, you can use NAIBRD_SER_INITIATE_BIT_NOWAIT_RESULT to initiate BIT without waiting, and later poll with naibrd_SER_CheckBITComplete() and naibrd_SER_GetChanMappedStatus() to check the result.

Troubleshooting Reference

Error / Symptom Possible Causes Suggested Resolution

BIT fails (non-success status)

Hardware fault on the channel, channel not fully disabled

Ensure the channel and its pair are both disabled. If the test continues to fail, the channel may have a hardware issue.

BIT timeout

Channel not disabled, pair channel not disabled

Verify both the selected channel and its pair are disabled before initiating BIT.

No board found or connection timeout

Board not powered, incorrect configuration file

Verify hardware is powered and connected.

Module not present at selected slot

No SER module installed

Verify hardware configuration.

BIT not supported on module

Module does not support BIT

Check your module type. Consult the SC3 Manual for BIT support.

Full Source

The complete source for this sample is provided below for reference.

Full Source — ser_bit.c (SSK 2.x)
/* nailib include files */
#include "nai_libs/nailib/include/naitypes.h"
#include "nai_libs/nailib/include/nailib.h"
#include "nai_libs/nailib/include/nailib_utils.h"

/* naibrd include files */
#include "nai_libs/naibrd/include/naibrd.h"
#include "nai_libs/naibrd/include/functions/naibrd_ser.h"

/* naiif include files */
#include "nai_libs/naiif/include/naiif_stdio.h"

/* Common Sample Program include files */
#include "nai_sample_apps/naiapp_common/include/naiapp_boardaccess_menu.h"
#include "nai_sample_apps/naiapp_common/include/naiapp_boardaccess_query.h"
#include "nai_sample_apps/naiapp_common/include/naiapp_boardaccess_access.h"
#include "nai_sample_apps/naiapp_common/include/naiapp_boardaccess_display.h"
#include "nai_sample_apps/naiapp_common/include/naiapp_boardaccess_utils.h"

static const int8_t *CONFIG_FILE = (const int8_t *)"default_SER_BIT.txt";

/* Function prototypes */
void Run_SER_BIT(int32_t cardIndex, int32_t module, uint32_t moduleID);

/**************************************************************************************************************/
/** \defgroup SERBIT

\brief This sample application demonstrates how to run a built-in-test (BIT) on a serial module.

The Serial built-in-test sample application illustrates the methods to call in the naibrd library to run the built-in-test on the serial
module.

To run BIT, ensure the selected channel is disabled, BIT will not run if the channel is enabled. (Channels need to be disabled in pairs: 1 &
2, 2 & 3, etc., otherwise BIT will timeout.) Start BIT by calling `naibrd_SER_InitiateBIT()`, passing in
`NAIBRD_SER_INITIATE_BIT_WAIT_RESULT` as the last argument to this function will wait until the test is finished and return its value. If
you pass in NAIBRD_SER_INITIATE_BIT_NOWAIT_RESULT the program will not wait for the result of the BIT to come back. You can check it at a
later time by using naibrd_SER_CheckBITComplete() and naibrd_SER_GetChanMappedStatus().

The main steps include:
- Querying the user for the card index and module number.
- Disabling the selected channel.
- Running the built-in-test on the serial module.
- Checking and displaying the test results.
- Restoring the channel's original state.
*/
/**************************************************************************************************************/
#ifdef NAIBSP_CONFIG_SOFTWARE_OS_VXWORKS
int32_t SER_BIT_Sample(void)
#else
int32_t main(void)
#endif
{
   bool_t stop = NAI_FALSE;
   int32_t cardIndex;
   int32_t moduleCnt;
   int32_t module;
   uint32_t moduleID = 0;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

   if (naiapp_RunBoardMenu(CONFIG_FILE) == NAI_TRUE)
   {
      while (stop != NAI_TRUE)
      {
         /* Query the user for the card index */
         stop = naiapp_query_CardIndex(naiapp_GetBoardCnt(), 0, &cardIndex);
         if (stop != NAI_TRUE)
         {
            check_status(naibrd_GetModuleCount(cardIndex, &moduleCnt));

            /* Query the user for the module number */
            stop = naiapp_query_ModuleNumber(moduleCnt, 1, &module);
            if (stop != NAI_TRUE)
            {
               check_status(naibrd_GetModuleName(cardIndex, module, &moduleID));
               if ((moduleID != 0))
               {
                  Run_SER_BIT(cardIndex, module, moduleID);
               }
            }
         }

         naiif_printf("\r\nType Q to quit or Enter key to restart application:\r\n");
         stop = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
      }
   }

   naiif_printf("\r\nType the Enter key to exit the program: ");
   naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
   naiapp_access_CloseAllOpenCards();

   return 0;
}

/**************************************************************************************************************/
/** \ingroup SERBIT
Configures a serial module, runs a built-in-test and checks the results.
\param cardIndex (Input) Logical Card Index assigned to connection with the NAI_BOARD (0 - NAI_MAX_CARDS-1).
\param module    (Input) Module Number of the module to access (1 - [max modules for board]).
\param moduleID  (Input) The ID of the module.
*/
/**************************************************************************************************************/
void Run_SER_BIT(int32_t cardIndex, int32_t module, uint32_t moduleID)
{
   int32_t channelCount, chanNum;
   bool_t bQuit = NAI_FALSE;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

   channelCount = naibrd_SER_GetChannelCount(moduleID);
   naiif_printf("\r\nSelect TX/RX Channel.");
   naiapp_query_ChannelNumber(channelCount, 1, &chanNum);

   naiif_printf ("\r\nSerial Channel # %d\r\n", chanNum);

   do
   {
      bool_t enable = 0;
      nai_status_t status;

      /* Get the state of the channel before BIT is executed.*/
      check_status(naibrd_SER_GetChannelEnable(cardIndex, module, chanNum, &enable));

      /* Disable the channel. Channels MUST be disabled for BIT to run. */
      check_status(naibrd_SER_SetChannelEnable(cardIndex, module, chanNum, NAI_FALSE));

      /* For BIT to run on the SC3 we need to make sure the channels are disabled in pairs (1&2, 2&3, etc.) */
      if (moduleID == NAIBRD_MODULE_ID_SC3 || moduleID == NAIBRD_MODULE_ID_SCB || moduleID == NAIBRD_MODULE_ID_CMR || moduleID == NAIBRD_MODULE_ID_IF3)
      {
         if ((chanNum % 2) == 0)   /* Even channel */
            check_status(naibrd_SER_SetChannelEnable(cardIndex, module, (chanNum - 1), NAI_FALSE));
         else
            check_status(naibrd_SER_SetChannelEnable(cardIndex, module, (chanNum + 1), NAI_FALSE));
      }
      else if (moduleID == NAIBRD_MODULE_ID_CMH)
      {
         /* The CMH Module only has five channels, so no need to disable its pair. */
         if (chanNum != 5)
         {
            if ((chanNum % 2) == 0)   /* Even channel */
               check_status(naibrd_SER_SetChannelEnable(cardIndex, module, (chanNum - 1), NAI_FALSE));
            else
               check_status(naibrd_SER_SetChannelEnable(cardIndex, module, (chanNum + 1), NAI_FALSE));
         }
      }

      /* Initiate BIT and wait for results */
      status = naibrd_SER_InitiateBIT(cardIndex, module, chanNum, NAIBRD_SER_INITIATE_BIT_WAIT_RESULT);

      if ( NAI_SUCCESS == status )
         naiif_printf("BIT Passed.\r\n");
      else
         check_status(status);

      /* Restore the channel's original state. */
      check_status(naibrd_SER_SetChannelEnable(cardIndex, module, chanNum, enable));

      naiif_printf("Press ENTER to run BIT again, or '%c' to exit program : ", NAI_QUIT_CHAR);
      bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);

   } while ( NAI_TRUE != bQuit );

   return;
}

Help Bot

X