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 Rx

SER ASync Rx Sample Application (SSK 1.x)

Overview

The SER ASync Rx sample application demonstrates how to configure a serial channel for asynchronous communication and receive data from an external transmitter using the NAI Software Support Kit (SSK 1.x). This is the receive-only counterpart to the SER ASync Tx sample, which handles the transmit side. Together they form a complete point-to-point async serial link. If you need to verify both directions without external hardware, use the SER ASync Loopback sample instead.

This sample supports the following SER module types: P8, PC, PD, Px, KB, SC, and newer SER variants. It also works with combination modules that include serial functionality, such as CMH. It serves as a practical API reference for implementing async serial reception using 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, SC, or newer SER variant).

  • SSK 1.x installed on your development host.

  • The sample applications built. Refer to the SSK 1.x build instructions for your platform if you have not already compiled them.

  • An external transmitter connected to the serial channel’s physical interface (RS-232, RS-422, or RS-485). Because this sample only receives, an external device must be actively sending data for the application to read anything. To generate test data, run the SER ASync Tx sample on another channel or board with matching serial parameters. To verify transmit and receive without external hardware, use the SER ASync Loopback sample instead.

How to Run

Launch the SER_ASync_Rx executable from your build output directory. On startup the application looks for a configuration file (default_SerASync_Rx.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 interface level, configures the channel, enables the receiver, and enters a receive loop that reads incoming data on demand until you quit.

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 1.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_Rx.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_GetModuleID() and verify it is non-zero before proceeding.

  5. Call Run_SER_ASync_Rx(cardIndex, module, moduleID) to configure the channel and begin receiving.

#if defined (__VXWORKS__)
int32_t SER_ASync_Rx_Sample(void)
#else
int32_t main(void)
#endif
{
   bool_t stop = 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) == TRUE)
   {
      while (stop != TRUE)
      {
         /* Query user for the card index */
         stop = naiapp_query_CardIndex(naiapp_GetBoardCnt(), 0, &cardIndex);
         if (stop != TRUE)
         {
            check_status(naibrd_GetModuleCount(cardIndex, &moduleCnt));

            /* Query user for the module number */
            stop = naiapp_query_ModuleNumber(moduleCnt, 1, &module);
            if (stop != TRUE)
            {
               moduleID = naibrd_GetModuleID(cardIndex, module);
               if ((moduleID != 0))
               {
                  Run_SER_ASync_Rx(cardIndex, module, moduleID);
               }
            }
         }

         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);
      }
   }

   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. 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_Rx_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_Rx(cardIndex, module, moduleID) to query for a channel and interface level, configure the channel, enable the receiver, and enter the receive loop.

  4. Prompt the user to quit or restart.

To run the receive operation, call Run_SER_ASync_Rx(cardIndex, module, moduleID) 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_GetModuleID(), used to determine hardware-specific behavior (for example, the 20 ms configuration settle delay on GEN 2/3 modules).

The sample defines three constants used throughout the receive operation:

  • MAX_DATA_RX (20) — the maximum number of words to read per receive call.

  • MAX_TIMEOUT (10) — a 10 ms general timeout (not directly used in the receive path).

  • CLEAR_FIFO_TIMEOUT (1000) — the number of polling iterations (at 1 ms each) to wait for FIFO clears to complete, giving a 1-second timeout.

Note
Unlike the SER ASync Tx sample, this application does not transmit any data. It only configures the receiver and reads incoming data. To generate test data, connect an external transmitter or run the Tx sample on a separate channel or board.

Interface Level Selection

Before configuring the channel, the sample queries the user for the physical interface level. This determines the electrical standard used on the physical connector and must match the transmitter’s interface.

The serial_query_interface() helper presents four options:

printf("Please select an interface type [default=1]:\n");
printf("1 - Loop-back\n");
printf("2 - RS232\n");
printf("3 - RS422\n");
printf("4 - RS485\n");

The selection maps to the corresponding nai_ser_interface_t constant:

  • 1 — NAI_SER_INTF_LOOPBACK (internal loopback, no external connection required)

  • 2 — NAI_SER_INTF_RS232 (point-to-point, single-ended)

  • 3 — NAI_SER_INTF_RS422 (point-to-point or multi-drop, differential)

  • 4 — NAI_SER_INTF_RS485 (multi-drop, differential, half-duplex)

For receiving data from an external transmitter, select option 2, 3, or 4 to match your physical connection. The loopback option is available for quick verification but will not receive external data — use the SER ASync Loopback sample for self-test scenarios instead. If the user enters an invalid choice, the function defaults to loopback and prints an error message.

Important

Common Errors

  • Interface level mismatch — if the selected interface level does not match the transmitter’s electrical standard, no data will be received (or the data will be garbled). For example, selecting RS-232 when the transmitter is sending RS-422 will produce no valid data. Both endpoints must use the same interface level.

  • RS-485 half-duplex considerations — RS-485 shares the same differential pair for transmit and receive. When receiving, the transmit driver must be disabled so it does not interfere with the incoming signal. Consult your module manual for RS-485 direction control details.

Channel Reset and FIFO Setup

Before enabling the receiver, reset the channel and clear both FIFOs to ensure no stale data remains from a previous operation. Leftover bytes in the Rx FIFO would be read back as if they were newly received data, producing misleading results.

Channel Reset

Issue a channel reset to return the channel to its default state:

naibrd_SER_ChannelReset(cardIndex, module, chanNum);

This call resets all channel configuration registers to their defaults. You must reconfigure the channel after calling this function.

Clearing the FIFOs

After the reset, explicitly clear both FIFOs:

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

These API calls request the hardware to flush the respective FIFOs. The requests are asynchronous — the hardware sets control-register bits while the clear is in progress and drops them once the operation completes. Although this is a receive-only application, the sample clears both FIFOs to leave the channel in a fully clean state.

Timeout Polling Pattern

After requesting the clear, poll the channel control register until the FIFO-clear bits are deasserted. The sample uses a 1 ms polling interval with a 1-second (1000-iteration) timeout:

nCntlValueLo = NAI_SER_CTRLLO_CLEAR_RX_FIFO | NAI_SER_CTRLLO_CLEAR_TX_FIFO;
for (i = 0; i < CLEAR_FIFO_TIMEOUT && (nCntlValueLo & (NAI_SER_CTRLLO_CLEAR_RX_FIFO | NAI_SER_CTRLLO_CLEAR_TX_FIFO)); i++)
{
   nai_ser_chanctrl chanCtrlRaw;
   naibrd_SER_GetChannelControlRaw(cardIndex, module, chanNum, &chanCtrlRaw);
   nCntlValueLo = chanCtrlRaw & 0x0000FFFF;
   nai_msDelay(1);
}
if (i == CLEAR_FIFO_TIMEOUT)
{
   printf("Unable to clear FIFOs %d\n", chanNum);
   printf("Please press Enter to exit...");
   while ((ch = getchar()) != 0x0A);
   return;
}

The loop reads the raw channel control word with naibrd_SER_GetChannelControlRaw(), masks it to the lower 16 bits, and checks whether NAI_SER_CTRLLO_CLEAR_RX_FIFO or NAI_SER_CTRLLO_CLEAR_TX_FIFO is still asserted. Each iteration sleeps 1 ms (nai_msDelay(1)), and CLEAR_FIFO_TIMEOUT is defined as 1000, giving a total wait of up to 1 second. If both bits clear before the timeout expires, the loop exits early and the application continues to channel configuration.

In your own application, implement a similar check to confirm FIFOs are cleared before proceeding. Skipping this verification can lead to stale data appearing in your first receive buffer.

Important

Common Errors

  • FIFO clear timeout — the FIFOs did not clear within 1 second. The channel may be in an unexpected state or the hardware may not be responding. Verify the module is operational and the channel is not locked by another process.

Channel Configuration

With the channel reset and FIFOs cleared, configure the serial channel for asynchronous reception. The configuration is identical to the SER ASync Tx and SER ASync Loopback samples — the same serial parameters must match on both the transmit and receive sides for communication to succeed.

Configuration APIs

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

check_status(naibrd_SER_SetProtocol(cardIndex, module, chanNum, NAI_SER_PROTOCOL_ASYNC));       /* Async mode */
check_status(naibrd_SER_SetInterfaceLevel(cardIndex, module, chanNum, interfaceLevel));         /* User-selected interface */
check_status(naibrd_SER_SetParity(cardIndex, module, chanNum, NAI_SER_PARITY_NONE));            /* No Parity */
check_status(naibrd_SER_SetDataBits(cardIndex, module, chanNum, 8));                            /* 8 Data Bits */
check_status(naibrd_SER_SetStopBits(cardIndex, module, chanNum, 1));                            /* 1 Stop Bits */
check_status(naibrd_SER_SetBaudrate(cardIndex, module, chanNum, 9600));                         /* 9600 baud */

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

  • naibrd_SER_SetProtocol() — sets the channel protocol to asynchronous mode (NAI_SER_PROTOCOL_ASYNC). Other options include HDLC and additional protocol modes defined by your module. The protocol must match the transmitter.

  • naibrd_SER_SetInterfaceLevel() — sets the physical interface level. The sample passes the interfaceLevel variable, which holds the user’s selection from serial_query_interface(). For receiving from an external transmitter, choose RS-232, RS-422, or RS-485 as appropriate for your cabling. Consult the module manual for the interface levels your module supports.

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

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

  • naibrd_SER_SetStopBits() — sets the number of stop bits. The sample uses 1. Use 2 stop bits when the remote transmitter is configured for 2.

  • naibrd_SER_SetBaudrate() — sets the baud rate. The sample uses 9600. Both endpoints must use the same baud rate. Consult the module manual for the full list of supported baud rates on your SER module variant.

Configuration Settle Delay (GEN 2/3 Modules)

After writing the configuration registers, the sample inserts a 20 ms delay for GEN 2/3 module types (P8, PC, PD, Px, KB) to allow the hardware to acknowledge the configuration change:

if (NAI_MODULE_ID_P8 == moduleID || NAI_MODULE_ID_PC == moduleID || NAI_MODULE_ID_PD == moduleID ||
   NAI_MODULE_ID_Px == moduleID || NAI_MODULE_ID_KB == moduleID)
{
   nai_msDelay(20);     /* Allow 20ms for the HW to acknowledge the configuration (GEN 2/3 only)*/
}

This delay applies only to older GEN 2/3 modules. Newer SER variants do not require the additional settle time.

Important

Common Errors

  • Configuration not taking effect — if the receiver does not recognize incoming data after configuration, verify that the settle delay has elapsed (for GEN 2/3 modules) and that all serial parameters match the transmitter.

  • 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.

  • NAI_ERROR_NOT_SUPPORTED — the protocol or interface level is not available for this module type. Check your module type and consult the module manual for supported protocols and interfaces.

Enabling the Receiver

After the channel is configured, enable the receiver so the hardware begins listening for incoming data on the physical interface:

check_status(naibrd_SER_SetReceiverEnable(cardIndex, module, chanNum, 1));

/* 100 millisecond wait to ensure the receiver is on. */
nai_msDelay(100);

naibrd_SER_SetReceiverEnable() with a value of 1 turns on the receiver for the specified channel. The 100 ms delay that follows gives the hardware time to fully activate the receiver circuitry before the application attempts to read data. In your own application, include a similar delay after enabling the receiver to avoid reading an empty FIFO before the hardware is ready.

Note
The SER ASync Tx sample does not enable the receiver — it only transmits. The SER ASync Loopback sample enables the receiver as well, since it reads back the looped data. This Rx sample enables the receiver but does not transmit, relying entirely on an external source for incoming data.
Important

Common Errors

  • No data received — if the Rx FIFO remains empty, verify that the receiver is enabled. Forgetting to call naibrd_SER_SetReceiverEnable() is one of the most common causes of a receive-only application appearing to do nothing.

  • Receiver enabled but no data arriving — the receiver is on, but no external transmitter is sending. Verify that the transmitter is active and connected to the correct channel with matching serial parameters.

Data Reception

With the receiver enabled and an external transmitter sending data, the Rx FIFO will accumulate incoming bytes. This section explains how the sample checks for available data and reads it back.

Checking the Rx Buffer Count

Before reading data, query the Rx FIFO to determine how many words are available:

naibrd_SER_GetRxBufferCnt(cardIndex, module, chanNum, (uint32_t*)&nNumWordsRecv);
printf("\nReading back %d words ...", nNumWordsRecv);

naibrd_SER_GetRxBufferCnt() returns the number of 32-bit words currently in the receive FIFO. If no data has arrived from the external transmitter, this count will be zero. In your own application, you can use this count to decide whether to read (skip the read if zero) or to allocate a buffer of the correct size.

Reading Data with ReceiveBuffer32

To read the data, call naibrd_SER_ReceiveBuffer32():

naibrd_SER_ReceiveBuffer32(cardIndex, module, chanNum, RecvDataStatus, MAX_DATA_RX, (uint32_t*)&nNumWordsRecv);
printf(" %d words read\n", nNumWordsRecv);

The parameters are:

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

  • RecvDataStatus — pointer to the output buffer (uint32_t[]). Each element contains both the received data byte and a status byte packed into a single 32-bit word.

  • MAX_DATA_RX — the maximum number of words the buffer can hold (20 in this sample).

  • (uint32_t*)&nNumWordsRecv — on return, updated with the number of words actually read from the FIFO. This may be less than MAX_DATA_RX if fewer words were available.

Understanding the 32-Bit Receive Format

Each word returned by naibrd_SER_ReceiveBuffer32() packs the received data and per-byte status into a single uint32_t. The sample decodes them as follows:

for (i = 0; i < nNumWordsRecv; i++)
   printf("Recd 0x%02X, Status= %02X\n",
   (RecvDataStatus[i] & 0x00FF), (RecvDataStatus[i] >> 8) & 0x00FF);
  • Bits [7:0] (RecvDataStatus[i] & 0x00FF) — the received data byte. For 8-bit data, this is the full character.

  • Bits [15:8] ((RecvDataStatus[i] >> 8) & 0x00FF) — the per-byte status flags. A status of 0x00 indicates a clean reception with no errors. Non-zero values indicate conditions such as parity error, framing error, or break detection. Consult your module’s manual for the full definition of the status bit fields.

In your own application, always check the status byte for each received word. A non-zero status indicates that the corresponding data byte may be corrupt. Common status conditions include:

  • Parity error — the received parity bit did not match the configured parity setting. Verify that both endpoints use the same parity mode.

  • Framing error — the stop bit was not detected at the expected position. This usually indicates a baud rate mismatch between transmitter and receiver.

  • Break condition — the receive line was held low for longer than one character time, indicating a break signal from the transmitter.

Receive Loop

The sample wraps the receive sequence in a do…​while loop that lets the user read data repeatedly:

do
{
   naibrd_SER_GetRxBufferCnt(cardIndex, module, chanNum, (uint32_t*)&nNumWordsRecv);
   printf("\nReading back %d words ...", nNumWordsRecv);
   naibrd_SER_ReceiveBuffer32(cardIndex, module, chanNum, RecvDataStatus, MAX_DATA_RX, (uint32_t*)&nNumWordsRecv);
   printf(" %d words read\n", nNumWordsRecv);

   for (i = 0; i < nNumWordsRecv; i++)
      printf("Recd 0x%02X, Status= %02X\n",
      (RecvDataStatus[i] & 0x00FF), (RecvDataStatus[i] >> 8) & 0x00FF);

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

} while (TRUE != bQuit);

Each iteration checks how many words are available, reads up to MAX_DATA_RX words, prints each word’s data and status, and then prompts the user to receive again or quit. The menu-driven loop is a sample convenience — in your own code, call naibrd_SER_GetRxBufferCnt() and naibrd_SER_ReceiveBuffer32() directly on whatever schedule your application requires (polling loop, timer interrupt, or event-driven).

Important

Common Errors

  • Zero words received — no data is available in the Rx FIFO. Verify that an external transmitter is connected, powered on, and actively sending data with matching serial parameters (baud rate, data bits, parity, stop bits, and interface level).

  • Status byte non-zero — one or more received bytes have error flags set. Check the specific status bits against your module manual. The most frequent causes are baud rate mismatch (framing errors) and parity setting mismatch (parity errors).

  • Fewer words than expected — naibrd_SER_ReceiveBuffer32() returns only the words currently in the FIFO, up to MAX_DATA_RX. If the transmitter has not finished sending, call the function again after a delay to retrieve additional data.

  • Rx FIFO overflow — if the transmitter sends data faster than the application reads it, the FIFO can overflow and data will be lost. In production applications, read the FIFO frequently or use interrupts to avoid overflow. Consult your module’s manual for the FIFO depth and overflow behavior.

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 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_Rx.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

FIFO clear timeout

Channel in an unexpected state, hardware not responding

Verify the module is operational and the channel is not locked by another process

NAI_ERROR_NOT_SUPPORTED

Protocol or interface level not available for this module type

Check your module type. Consult your module’s manual for supported protocols and interfaces.

No data received (zero words)

External transmitter not connected, not sending, or not configured with matching serial parameters; receiver not enabled

Verify the transmitter is active and connected. Confirm naibrd_SER_SetReceiverEnable() was called with a value of 1. Ensure baud rate, data bits, parity, stop bits, and interface level match on both endpoints.

Interface level mismatch

Selected RS-232 but transmitter is sending RS-422 (or vice versa)

Confirm the interface level passed to naibrd_SER_SetInterfaceLevel() matches the transmitter’s physical interface

Status byte non-zero (framing errors)

Baud rate mismatch between transmitter and receiver

Verify both endpoints use the same baud rate. Consult your module’s manual for supported baud rates.

Status byte non-zero (parity errors)

Parity setting mismatch between transmitter and receiver

Verify both endpoints use the same parity mode (none, odd, or even)

Fewer words than expected

Transmitter has not finished sending, or data arrived after the read call

Call naibrd_SER_GetRxBufferCnt() and naibrd_SER_ReceiveBuffer32() again after a short delay to retrieve additional data

Rx FIFO overflow / lost data

Application reads the FIFO too slowly relative to the incoming data rate

Increase the read frequency, use interrupts, or reduce the transmitter’s data rate. Consult your module’s manual for FIFO depth.

Invalid baud rate

Module does not support the requested baud rate

Consult your module’s manual for supported baud rates

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_Rx.c (SSK 1.x)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <ctype.h>

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

/* naibrd include files */
#include "nai.h"
#include "naibrd.h"
#include "functions/naibrd_ser.h"
#include "advanced/nai_ether_adv.h"

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

/* Function prototypes */
void Run_SER_ASync_Rx(int32_t cardIndex, int32_t module, uint32_t moduleID);
static void serial_query_interface(nai_ser_interface_t* interfaceLevel);

#define MAX_DATA_RX  20
#define MAX_TIMEOUT  10          /* 10ms timeout */
#define CLEAR_FIFO_TIMEOUT 1000  /* 1 second */

/**************************************************************************************************************/
/** \defgroup SERAsyncRx Serial Asynchronous Receive
The purpose of the Serial Asynchronous Receive sample application is to illustrate the methods to call in the
naibrd library to configure a given serial channel for receiving RS422. The SER_Async_Tx application can be run
in unison to this application to transmit data.
*/
/**************************************************************************************************************/
#if defined (__VXWORKS__)
int32_t SER_ASync_Rx_Sample(void)
#else
int32_t main(void)
#endif
{
   bool_t stop = 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) == TRUE)
   {
      while (stop != TRUE)
      {
         /* Query user for the card index */
         stop = naiapp_query_CardIndex(naiapp_GetBoardCnt(), 0, &cardIndex);
         if (stop != TRUE)
         {
            check_status(naibrd_GetModuleCount(cardIndex, &moduleCnt));

            /* Query user for the module number */
            stop = naiapp_query_ModuleNumber(moduleCnt, 1, &module);
            if (stop != TRUE)
            {
               moduleID = naibrd_GetModuleID(cardIndex, module);
               if ((moduleID != 0))
               {
                  Run_SER_ASync_Rx(cardIndex, module, moduleID);
               }
            }
         }

         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);
      }
   }

   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 SERAsyncRx
Configures a serial module for asynchronous receiving. The user is queried for the serial channel to receive 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_Rx(int32_t cardIndex, int32_t module, uint32_t moduleID)
{
   int32_t ch, i;
   int32_t channelCount;
   int32_t chanNum;
   int32_t nCntlValueLo;
   int32_t nNumWordsRecv = 0;
   uint32_t RecvDataStatus[MAX_DATA_RX];
   bool_t bQuit = FALSE;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;
   nai_ser_interface_t interfaceLevel = NAI_SER_INTF_LOOPBACK;

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

   naibrd_SER_ChannelReset(cardIndex, module, chanNum);
   naibrd_SER_ClearRxFifo(cardIndex, module, chanNum);
   naibrd_SER_ClearTxFifo(cardIndex, module, chanNum);
   nCntlValueLo = NAI_SER_CTRLLO_CLEAR_RX_FIFO | NAI_SER_CTRLLO_CLEAR_TX_FIFO;
   for (i = 0; i < CLEAR_FIFO_TIMEOUT && (nCntlValueLo & (NAI_SER_CTRLLO_CLEAR_RX_FIFO | NAI_SER_CTRLLO_CLEAR_TX_FIFO)); i++)
   {
      nai_ser_chanctrl chanCtrlRaw;
      naibrd_SER_GetChannelControlRaw(cardIndex, module, chanNum, &chanCtrlRaw);
      nCntlValueLo = chanCtrlRaw & 0x0000FFFF;
      nai_msDelay(1);
   }
   if (i == CLEAR_FIFO_TIMEOUT)
   {
      printf("Unable to clear FIFOs %d\n", chanNum);
      printf("Please press Enter to exit...");
      while ((ch = getchar()) != 0x0A);
      return;
   }

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

   /* Configure for ASync on the channel selected. */
   check_status(naibrd_SER_SetProtocol(cardIndex, module, chanNum, NAI_SER_PROTOCOL_ASYNC));       /* Async mode */
   check_status(naibrd_SER_SetInterfaceLevel(cardIndex, module, chanNum, interfaceLevel));         /* Loopback, RS232, RS422, or RS485 */
   check_status(naibrd_SER_SetParity(cardIndex, module, chanNum, NAI_SER_PARITY_NONE));            /* No Parity */
   check_status(naibrd_SER_SetDataBits(cardIndex, module, chanNum, 8));                            /* 8 Data Bits */
   check_status(naibrd_SER_SetStopBits(cardIndex, module, chanNum, 1));                            /* 1 Stop Bits */
   check_status(naibrd_SER_SetBaudrate(cardIndex, module, chanNum, 9600));                         /* 9600 baud */
   if (NAI_MODULE_ID_P8 == moduleID || NAI_MODULE_ID_PC == moduleID || NAI_MODULE_ID_PD == moduleID ||
      NAI_MODULE_ID_Px == moduleID || NAI_MODULE_ID_KB == moduleID)
   {
      nai_msDelay(20);     /* Allow 20ms for the HW to acknowledge the configuration (GEN 2/3 only)*/
   }
   check_status(naibrd_SER_SetReceiverEnable(cardIndex, module, chanNum, 1));                      /* Enable the Receiver */

   /* 100 millisecond wait to ensure the receiver is on. */
   nai_msDelay(100);

   printf("Please press Enter to read back data...");
   while ((ch = getchar()) != 0x0A);

   do
   {
      naibrd_SER_GetRxBufferCnt(cardIndex, module, chanNum, (uint32_t*)&nNumWordsRecv);
      printf("\nReading back %d words ...", nNumWordsRecv);
      naibrd_SER_ReceiveBuffer32(cardIndex, module, chanNum, RecvDataStatus, MAX_DATA_RX, (uint32_t*)&nNumWordsRecv); /* read back data */
      printf(" %d words read\n", nNumWordsRecv);

      for (i = 0; i < nNumWordsRecv; i++)
         printf("Recd 0x%02X, Status= %02X\n",
         (RecvDataStatus[i] & 0x00FF), (RecvDataStatus[i] >> 8) & 0x00FF);

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

   } while (TRUE != bQuit);

   return;
}

/**************************************************************************************************************/
/** \ingroup SERAsyncRx
Queries the user for the interface type.
\param interfaceLevel (Output) The selected interface level.
*/
/**************************************************************************************************************/
static void serial_query_interface(nai_ser_interface_t* interfaceLevel)
{
   int8_t inputBuffer[80];
   int32_t choice;

   printf("Please select an interface type [default=1]:\n");
   printf("1 - Loop-back\n");
   printf("2 - RS232\n");
   printf("3 - RS422\n");
   printf("4 - RS485\n");
   printf("Enter choice: ");
   fgets((char*)inputBuffer, sizeof(inputBuffer), stdin);
   choice = atoi((char*)inputBuffer);

   switch (choice)
   {
   case 1:
      *interfaceLevel = NAI_SER_INTF_LOOPBACK;
      break;
   case 2:
      *interfaceLevel = NAI_SER_INTF_RS232;
      break;
   case 3:
      *interfaceLevel = NAI_SER_INTF_RS422;
      break;
   case 4:
      *interfaceLevel = NAI_SER_INTF_RS485;
      break;
   default:
      printf("ERROR: Invalid choice. Defaulting to Loop-back.\n");
      *interfaceLevel = NAI_SER_INTF_LOOPBACK;
      break;
   }

   return;
}

Help Bot

X