SER BIT
Edit this on GitLab
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.
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:
-
Call
naiapp_RunBoardMenu()to load a saved configuration file or present the interactive board menu. -
Query the user for a card index and module slot.
-
Retrieve the module ID with
naibrd_GetModuleName(). -
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:
|
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;
}