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 Async Loopback

SER Async Loopback Sample Application (SSK 2.x)

Overview

The SER Async Loopback sample application demonstrates how to configure a serial channel for asynchronous communication and run an internal loopback test using the NAI Software Support Kit (SSK 2.x). The application configures a channel for async mode with internal loopback, writes 100 words to the transmit FIFO, loops them back through the module’s internal path, and reads them back for verification. This exercises the complete transmit-to-receive data path without requiring any external cabling.

This sample supports SER module types including P8, PC, PD, Px, KB, and newer SER variants. It also works with combination modules that include serial functionality, such as CMH. It serves as a practical API reference — each step maps directly to naibrd_SER_*() API calls that you can lift into your own code.

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

Prerequisites

Before running this sample, make sure you have:

  • An NAI board with a SER module installed (P8, PC, PD, Px, KB, or newer SER variant).

  • 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_async_loopback executable from your build output directory. On startup the application looks for a configuration file (default_SerAsync_Loopback.txt). On the first run, this file will not exist — the application will present an interactive board menu where you configure a board connection, card index, and module slot. You can save this configuration so that subsequent runs skip the menu and connect automatically. Once connected, the application queries for a channel number and executes a single loopback test.

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 (if one exists) or present the interactive board menu. The configuration file (default_SerAsync_Loopback.txt) is not included with the SSK — it is created when the user saves their connection settings from the board menu. On the first run, the menu will always appear.

  2. Query the user for a card index with naiapp_query_CardIndex().

  3. Query for a module slot with naiapp_query_ModuleNumber().

  4. Retrieve the module ID with naibrd_GetModuleName() so downstream code can adapt to the specific SER variant installed.

  5. Call Run_SER_ASync_Loopback(cardIndex, module, moduleID) to query for a channel and execute the loopback test.

#ifdef NAIBSP_CONFIG_SOFTWARE_OS_VXWORKS
int32_t SER_ASync_Loopback_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_ASync_Loopback(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;
}

Note the SSK 2.x differences from SSK 1.x in this startup sequence:

  • The VxWorks preprocessor guard uses NAIBSP_CONFIG_SOFTWARE_OS_VXWORKS (SSK 1.x uses __VXWORKS__).

  • The module identifier is retrieved with naibrd_GetModuleName() (SSK 1.x uses naibrd_GetModuleID()).

  • Boolean constants are NAI_TRUE / NAI_FALSE (SSK 1.x uses TRUE / FALSE).

  • Console output uses naiif_printf() from the platform abstraction layer (SSK 1.x uses printf() directly).

Important

Common connection errors you may encounter at this stage:

  • No board found — verify that the board is powered on and physically connected. Check that the configuration file lists the correct interface and address.

  • Connection timeout — confirm network settings (for Ethernet connections) or bus configuration (for PCI/PCIe). Firewalls and IP mismatches are frequent causes.

  • Invalid card or module index — indices are zero-based for cards and one-based for modules. Ensure the values you pass match your hardware setup.

  • Module not present at selected slot — the slot you selected does not contain a SER module. Use the board menu to verify which slots are populated.

Program Structure

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

The startup flow proceeds as follows:

  1. Load the saved configuration (or present the board menu) via naiapp_RunBoardMenu().

  2. Query the user for card index, module slot, and retrieve the module ID.

  3. Call Run_SER_ASync_Loopback(cardIndex, module, moduleID) to query for a channel and execute the loopback test.

  4. Prompt the user to quit or restart.

Note
Unlike menu-driven samples (such as AD BasicOps), this sample executes a single loopback test and returns. There is no interactive command loop.

To run the loopback test, call Run_SER_ASync_Loopback() with three parameters:

  • cardIndex — the logical card index for the board connection.

  • module — the one-based module slot number.

  • moduleID — the module ID returned by naibrd_GetModuleName(), used to determine hardware-specific behavior.

Channel Reset and FIFO Clearing

Before configuring a channel for a loopback test, reset the channel and clear both FIFOs. Leftover data from a previous operation can corrupt the test, so this should be the first thing you do after selecting a channel.

Resetting the Channel

To reset the serial channel to its default state, call naibrd_SER_ChannelReset():

naibrd_SER_ChannelReset(cardIndex, module, chanNum);

This restores all channel registers to their power-on defaults. Any previously configured protocol, baud rate, or interface setting is cleared. In your own application, use a channel reset when you need a clean starting state — for example, when switching a channel between protocols or recovering from an error condition.

Clearing the FIFOs

After the reset, explicitly clear both the receive and transmit FIFOs:

naibrd_SER_ClearRxFifo(cardIndex, module, chanNum);
naibrd_SER_ClearTxFifo(cardIndex, module, chanNum);

These API calls flush any data remaining in the respective FIFOs. The SSK 2.x version of this sample issues the reset and FIFO clears without the timeout-polling loop found in the SSK 1.x counterpart — the channel reset ensures the hardware is in a known state before the clears are issued.

Important

Common Errors

  • Stale data in FIFO — if you skip the channel reset or FIFO clear, leftover bytes from a previous test can appear in your receive data. Always reset and clear before starting a new loopback.

Channel Configuration

The sample configures the serial channel with a standard set of asynchronous parameters. In your own application, call the same APIs with values that match your communication requirements — the defaults shown here are a common starting point, but every parameter can be adjusted independently.

Configuration APIs

The following block sets the protocol, interface, parity, data bits, stop bits, baud rate, and receiver enable for the selected channel:

check_status(naibrd_SER_SetCommProtocol(cardIndex, module, chanNum, NAIBRD_SER_PROTOCOL_ASYNC));  /* Async mode  */
check_status(naibrd_SER_SetInterface(cardIndex, module, chanNum, NAIBRD_SER_INTF_LOOPBACK));      /* LoopBack    */
check_status(naibrd_SER_SetParityType(cardIndex, module, chanNum, NAIBRD_SER_PARITY_NONE));       /* No Parity   */
check_status(naibrd_SER_SetNumDataBits(cardIndex, module, chanNum, NAIBRD_SER_DATA_BITS_8));      /* 8 Data Bits */
check_status(naibrd_SER_SetNumStopBits(cardIndex, module, chanNum, NAIBRD_SER_STOP_BITS_1));      /* 1 Stop Bit  */
check_status(naibrd_SER_SetBaudrate(cardIndex, module, chanNum, 9600));                           /* 9600 baud   */
check_status(naibrd_SER_SetReceiverEnable(cardIndex, module, chanNum, NAI_TRUE));                 /* Enable Rx   */

Each call is explained below with the sample’s default value and the available alternatives:

  • naibrd_SER_SetCommProtocol() — sets the channel protocol to asynchronous mode (NAIBRD_SER_PROTOCOL_ASYNC). Other options include HDLC and additional protocol modes defined by your module. Select the protocol that matches your data-link requirements.

  • naibrd_SER_SetInterface() — sets the physical interface. The sample uses NAIBRD_SER_INTF_LOOPBACK, which routes the transmit output directly back to the receive input inside the module — no external wiring is needed. For external communication, choose RS-232, RS-422, or RS-485 as appropriate for your cabling and hardware. Consult the SC-05 Manual for the interface levels your module supports.

  • naibrd_SER_SetParityType() — sets the parity mode. The sample uses NAIBRD_SER_PARITY_NONE. Other options are odd and even parity. Both endpoints in a link must agree on the same parity setting, or every received frame will flag a parity error.

  • naibrd_SER_SetNumDataBits() — sets the number of data bits per character. The sample uses NAIBRD_SER_DATA_BITS_8, which is the most common setting. 7-bit mode is also available for legacy protocols that use 7-bit ASCII.

  • naibrd_SER_SetNumStopBits() — sets the number of stop bits. The sample uses NAIBRD_SER_STOP_BITS_1. Use 2 stop bits when the remote device requires extra inter-character spacing.

  • naibrd_SER_SetBaudrate() — sets the baud rate in bits per second. The sample uses 9600. NAI serial modules support a wide range of standard baud rates. Consult the SC-05 Manual for the full list of supported baud rates on your SER module variant.

  • naibrd_SER_SetReceiverEnable() — enables the receive path on the channel. Set to NAI_TRUE to enable. In this sample, the receiver is enabled as part of the initial configuration so it is ready to capture loopback data as soon as transmission begins.

Understanding Internal Loopback

When you set the interface to NAIBRD_SER_INTF_LOOPBACK, the NAI serial module connects the channel’s transmitter output directly to its receiver input at the hardware level. This creates a closed loop within the module — data you write to the transmit FIFO will appear in the receive FIFO after the configured serial framing (start bit, data bits, parity, stop bits) is applied. The loopback path exercises the full serialization and deserialization logic of the channel, making it a reliable way to verify that the channel is functioning correctly before connecting external equipment.

Because the loopback is internal, the baud rate controls how fast data moves through the serialization path. At 9600 baud with 8N1 framing (10 bits per character including start and stop), each byte takes approximately 1.04 ms to serialize and deserialize. The 100-word test payload in this sample therefore takes roughly 104 ms to complete the round trip.

Configuration Readiness Delay

After setting all parameters, the sample inserts a 100 ms delay before transmitting:

naibrd_msDelay(100);

This pause gives the hardware time to apply the configuration and prepare the receiver. If you shorten or remove this delay, early transmitted bytes may be lost because the receive path is not yet fully initialized. The exact timing depends on your module variant — consult the SC-05 Manual for guidance on configuration settling times.

Note
The SSK 2.x API names differ from the SSK 1.x versions. For example, naibrd_SER_SetCommProtocol() replaces naibrd_SER_SetProtocol(), naibrd_SER_SetInterface() replaces naibrd_SER_SetInterfaceLevel(), and naibrd_SER_SetParityType() replaces naibrd_SER_SetParity(). The underlying hardware behavior is the same.
Important

Common Errors

  • NAI_ERROR_NOT_SUPPORTED — the protocol or interface level is not available for this module type. Check that your module supports the selected protocol. Consult the SC-05 Manual for supported modes.

  • Receiver not enabled — if you omit the call to naibrd_SER_SetReceiverEnable(), the channel will transmit but no data will appear in the receive FIFO. Always enable the receiver before transmitting in a loopback test.

  • Invalid baud rate — not all baud rates are supported by every SER module variant. If the channel does not communicate at the expected speed, consult the module manual for the list of valid rates.

Data Transmission

With the channel configured, the application builds a test payload, loads it into the transmit FIFO, and initiates the transfer. The SSK 2.x version uses a two-step transmit model: first load the FIFO, then explicitly trigger transmission.

Building Test Data

The sample populates an array of 100 words with incremental values starting at 0x31:

#define NUM_DATA_TX  100

for (numWordsToSend = 0; numWordsToSend < NUM_DATA_TX; numWordsToSend++)
{
   SendData[numWordsToSend] = (uint8_t)(numWordsToSend + 0x31);
   naiif_printf("txData[%2i] = 0x%X\r\n", numWordsToSend, SendData[numWordsToSend]);
}

The payload consists of values 0x31 through 0x94, which correspond to printable ASCII characters starting at '1'. In your own application, populate the buffer with whatever payload you need to send — the API does not impose restrictions on the data content. The NUM_DATA_TX constant controls the payload size.

Loading the Transmit FIFO

To load data into the transmit FIFO, call naibrd_SER_LoadBufferWithTimeOut32():

check_status(naibrd_SER_LoadBufferWithTimeOut32(cardIndex, module, chanNum,
   SendData, numWordsToSend, NUM_DATA_TX, NAIBRD_FIFO_TIMEOUT_NONE, &numWordsToSend));

The parameters are:

  • cardIndex, module, chanNum — identify the target channel.

  • SendData — pointer to the data buffer.

  • numWordsToSend (input) — the number of words to load into the FIFO.

  • NUM_DATA_TX — the maximum FIFO capacity for this transfer.

  • NAIBRD_FIFO_TIMEOUT_NONE — do not wait for FIFO space; fail immediately if the FIFO is full. Use a timeout value if your application may write more data than the FIFO can hold in a single call.

  • &numWordsToSend (output) — on return, updated with the number of words actually loaded. Compare the output against the input to confirm all data was accepted.

This is an SSK 2.x-specific API. The SSK 1.x counterpart uses naibrd_SER_TransmitBuffer(), which combines loading and initiating transmission in a single call.

Initiating Transmission

After loading the FIFO, the sample waits 100 ms for the buffer to settle, then explicitly triggers the transmission:

naibrd_msDelay(100);

check_status(naibrd_SER_TransmitInitiate(cardIndex, module, chanNum));
naiif_printf(" %d words sent\r\n", numWordsToSend);

naibrd_SER_TransmitInitiate() tells the hardware to begin serializing and transmitting the data currently in the FIFO. Data does not leave the FIFO until you call this function (unless the channel is configured for "transmit always" mode, which continuously drains the FIFO). This two-step model — load then initiate — gives you precise control over when transmission begins, which is important for protocols that require coordinated timing between endpoints.

Important

Common Errors

  • FIFO overflow — if the number of words loaded exceeds the FIFO depth, the excess data is silently dropped. Check the return value of naibrd_SER_LoadBufferWithTimeOut32() to verify all words were accepted.

  • Missing transmit initiate — in SSK 2.x, calling naibrd_SER_LoadBufferWithTimeOut32() alone does not start transmission. You must also call naibrd_SER_TransmitInitiate() or the data will sit in the FIFO indefinitely.

Data Reception and Verification

After transmission, the application reads back the loopback data and displays it alongside per-word status information. This step confirms that the channel’s transmit and receive paths are working correctly.

Waiting for Loopback Data

The sample prompts the user to press Enter before reading data, giving the internal loopback path time to complete:

naiif_printf("Please press Enter to read back data...");
while (naiapp_query_ForQuitResponse(sizeof(inputBuffer), 0x0A, inputBuffer, &inputResponseCnt));

In your own application, you would typically poll naibrd_SER_GetRxBufferCnt() or use a timed delay instead of waiting for user input. The loopback latency depends on the baud rate and payload size — at 9600 baud with 100 bytes of 8N1 data, expect approximately 104 ms for all data to arrive.

Checking the Receive Count

Before reading data, query the number of words available in the receive FIFO:

naibrd_SER_GetRxBufferCnt(cardIndex, module, chanNum, (uint32_t*)&numWordsToRead);
naiif_printf("\r\nReading back %d words ...", numWordsToRead);

This call writes the current receive-buffer word count into numWordsToRead. In a successful loopback test, this value should equal the number of words you transmitted (100).

Reading Received Data

To read the received data, call naibrd_SER_ReceiveBufferWithTimeOut32():

check_status(naibrd_SER_ReceiveBufferWithTimeOut32(cardIndex, module, chanNum,
   RecvData, NUM_DATA_RX, numWordsToRead, NAIBRD_FIFO_TIMEOUT_NONE, &numWordsToRead));
naiif_printf(" %d words read\r\n", numWordsToRead);

The parameters are:

  • cardIndex, module, chanNum — identify the source channel.

  • RecvData — pointer to the receive buffer.

  • NUM_DATA_RX — the maximum buffer capacity.

  • numWordsToRead (input) — the number of words to read from the FIFO.

  • NAIBRD_FIFO_TIMEOUT_NONE — do not wait for data; return immediately with whatever is available.

  • &numWordsToRead (output) — on return, updated with the number of words actually read.

Each element of RecvData is a 32-bit word that packs both the data byte and a per-word status indicator:

  • Lower byte (RecvData[i] & 0x00FF) — the received data byte.

  • Upper byte ((RecvData[i] >> 8) & 0x00FF) — per-word status flags (parity error, framing error, etc.).

Displaying Results

The sample prints each received word with its data and status bytes:

for (i = 0; i < numWordsToRead; i++)
{
   naiif_printf("rxData[%2i] = 0x%02X, Status = 0x%02X\r\n",
      i, (RecvData[i] & 0x00FF), (RecvData[i] >> 8) & 0x00FF);
}

In a correctly configured loopback, the received data byte at each index should match the transmitted value, and the status byte should be 0x00 (no errors). For example, txData[0] = 0x31 should produce rxData[0] = 0x31, Status = 0x00. A non-zero status byte indicates a per-word error such as a parity or framing fault.

Important

Common Errors

  • Received count does not match sent count — the receiver was not enabled before transmitting, or the configuration readiness delay was too short. Verify that naibrd_SER_SetReceiverEnable() was called with NAI_TRUE and that the delay after configuration is sufficient for your baud rate.

  • Non-zero status byte — a parity or framing error was detected on the received word. In a loopback test this typically indicates a configuration mismatch or hardware issue, since both the transmitter and receiver share the same settings. Verify the channel configuration and try a channel reset.

  • No data received (receive count is zero) — the receiver is not enabled, naibrd_SER_TransmitInitiate() was not called, or the interface is not set to loopback. Double-check the enable state, transmit initiation, and interface setting.

  • Partial data received — the receive FIFO was read before the full payload had time to arrive. At 9600 baud, 100 bytes of 8N1 data takes approximately 104 ms. Increase the delay or poll the receive count until it matches the expected value.

Troubleshooting Reference

This table summarizes common errors and symptoms covered in the sections above. For detailed context on each entry, refer to the relevant section. Consult your module’s manual (for example, the SC-05 Manual) for hardware-specific diagnostic procedures.

Error / Symptom Possible Causes Suggested Resolution

No board found or connection timeout

Board not powered, incorrect or missing configuration file, network issue

Verify hardware is powered and connected. If default_SerAsync_Loopback.txt exists, check that it lists the correct interface and address. If it does not exist, the board menu will appear — configure and save your connection settings.

Module not detected at selected slot

No module installed at the specified slot, incorrect module number entered

Verify hardware configuration and module slot assignment.

NAI_ERROR_NOT_SUPPORTED

Protocol or interface level not available for this module type

Check your module type. Consult the SC-05 Manual for supported protocols and interfaces.

Stale data in receive FIFO

Channel not reset or FIFOs not cleared before starting the test

Call naibrd_SER_ChannelReset() followed by naibrd_SER_ClearRxFifo() and naibrd_SER_ClearTxFifo() before configuring the channel.

No data received

Receiver not enabled, transmit not initiated, interface not set to loopback

Verify naibrd_SER_SetReceiverEnable() was called with NAI_TRUE, naibrd_SER_TransmitInitiate() was called after loading the FIFO, and interface is set to NAIBRD_SER_INTF_LOOPBACK.

Received count does not match sent count

Receiver not enabled before transmitting, configuration delay too short

Verify receiver is enabled. Increase the post-configuration delay. At 9600 baud 8N1, allow at least 104 ms for 100 bytes.

Status byte indicates error

Parity or framing error detected during reception

In loopback mode both endpoints share the same settings, so this typically indicates a hardware issue. Try resetting the channel and reconfiguring.

FIFO overflow (fewer words loaded than requested)

Payload exceeds FIFO depth

Check the return value from naibrd_SER_LoadBufferWithTimeOut32(). Reduce the payload size or send in multiple batches.

Data sits in FIFO, never transmits

naibrd_SER_TransmitInitiate() not called after loading the FIFO

SSK 2.x uses a two-step model: load the FIFO, then call naibrd_SER_TransmitInitiate() to begin transmission.

Invalid baud rate

Module does not support the requested baud rate

Consult the SC-05 Manual for supported baud rates on your SER module variant.

Full Source

The complete source for this sample is provided below for reference. The sections above explain each part in detail.

Full Source — ser_async_loopback.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_SerAsync_Loopback.txt";

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

#define NUM_DATA_TX  100              /* Number of words to transmit */
#define NUM_DATA_RX  NUM_DATA_TX

/**************************************************************************************************************/
/** \defgroup SERLoopbackAsync

\brief This sample application demonstrates how to configure and use a serial channel for asynchronous loopback transmission.

The Serial Loopback Asynchronous Sample Application illustrates the methods to call in the naibrd library to configure a given
serial channel for loopback transmission. The application writes data to the selected serial channel's transmit buffer, transmits
it via an internal loopback, and receives and prints the data.

The main steps include:
- Querying the user for the card index and module number.
- Configuring the serial channel for asynchronous communication with loopback.
- Transmitting data through the serial channel.
- Receiving the transmitted data and displaying it.
*/
/**************************************************************************************************************/
#ifdef NAIBSP_CONFIG_SOFTWARE_OS_VXWORKS
int32_t SER_ASync_Loopback_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_ASync_Loopback(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 SERLoopbackAsync
Configures a serial module for asynchronous internal loopback transmission. The user is queried for the
serial channel to perform this transmission on.
\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_ASync_Loopback(int32_t cardIndex, int32_t module, uint32_t moduleID)
{
   int32_t i;
   int32_t channelCount;
   int32_t chanNum;
   uint32_t SendData[NUM_DATA_TX];
   uint32_t RecvData[NUM_DATA_RX];
   int32_t numWordsToSend = 0;
   int32_t numWordsToRead = 0;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

   channelCount = naibrd_SER_GetChannelCount(moduleID);
   naiapp_query_ChannelNumber(channelCount, 1, &chanNum);

   naibrd_SER_ChannelReset(cardIndex, module, chanNum);
   naibrd_SER_ClearRxFifo(cardIndex, module, chanNum);
   naibrd_SER_ClearTxFifo(cardIndex, module, chanNum);

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

   /* Configure for ASync on the channel selected. */
   check_status(naibrd_SER_SetCommProtocol(cardIndex, module, chanNum, NAIBRD_SER_PROTOCOL_ASYNC));      /* Async mode  */
   check_status(naibrd_SER_SetInterface(cardIndex, module, chanNum, NAIBRD_SER_INTF_LOOPBACK));          /* LoopBack    */
   check_status(naibrd_SER_SetParityType(cardIndex, module, chanNum, NAIBRD_SER_PARITY_NONE));           /* No Parity   */
   check_status(naibrd_SER_SetNumDataBits(cardIndex, module, chanNum, NAIBRD_SER_DATA_BITS_8));          /* 8 Data Bits */
   check_status(naibrd_SER_SetNumStopBits(cardIndex, module, chanNum, NAIBRD_SER_STOP_BITS_1));          /* 1 Stop Bit  */
   check_status(naibrd_SER_SetBaudrate(cardIndex, module, chanNum, 9600));                               /* 9600 baud   */
   check_status(naibrd_SER_SetReceiverEnable(cardIndex, module, chanNum, NAI_TRUE));                     /* Enable the Receiver */

   /* Populate array with data to send */
   for (numWordsToSend = 0; numWordsToSend < NUM_DATA_TX; numWordsToSend++)
   {
      SendData[numWordsToSend] = (uint8_t)(numWordsToSend + 0x31);  /* incremental data */
      naiif_printf("txData[%2i] = 0x%X\r\n", numWordsToSend, SendData[numWordsToSend]);
   }

   /* Wait for configuration to be ready */
   naibrd_msDelay(100);

   /***   Transmit Data   ***/
   naiif_printf("Sending %d words ...", numWordsToSend);

   /* Load FIFO with data from the array */
   check_status(naibrd_SER_LoadBufferWithTimeOut32(cardIndex, module, chanNum, SendData, numWordsToSend, NUM_DATA_TX,
      NAIBRD_FIFO_TIMEOUT_NONE, &numWordsToSend));

   /* Wait for buffer to load */
   naibrd_msDelay(100);

   /* Initiate Transmit - Data does not transmit until we tell it to (or if we have it in "Transmit Always" mode) */
   check_status(naibrd_SER_TransmitInitiate(cardIndex, module, chanNum));
   naiif_printf(" %d words sent\r\n", numWordsToSend);

   /***   Receive Data   ***/
   naiif_printf("Please press Enter to read back data...");
   while (naiapp_query_ForQuitResponse(sizeof(inputBuffer), 0x0A, inputBuffer, &inputResponseCnt));

   /* Check how many words we have waiting in the RX buffer */
   naibrd_SER_GetRxBufferCnt(cardIndex, module, chanNum, (uint32_t*)&numWordsToRead);
   naiif_printf("\r\nReading back %d words ...", numWordsToRead);

   /* Read data stored in the RX buffer */
   check_status(naibrd_SER_ReceiveBufferWithTimeOut32(cardIndex, module, chanNum, RecvData, NUM_DATA_RX, numWordsToRead, NAIBRD_FIFO_TIMEOUT_NONE,
      &numWordsToRead));
   naiif_printf(" %d words read\r\n", numWordsToRead);

   /* Print buffer contents - First 8 bits are for data, last 8 bits are status */
   for (i = 0; i < numWordsToRead; i++)
   {
      naiif_printf("rxData[%2i] = 0x%02X, Status = 0x%02X\r\n", i, (RecvData[i] & 0x00FF), (RecvData[i] >> 8) & 0x00FF);
   }
   naiif_printf("Press ENTER to receive again, or '%c' to exit program : ", NAI_QUIT_CHAR);
   naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);

   return;
}

Help Bot

X