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 Xmit

SER Async Xmit Sample Application (SSK 2.x)

Overview

The SER Async Xmit sample application demonstrates how to configure a serial channel for asynchronous transmission using the NAI Software Support Kit (SSK 2.x). The application configures a channel for async mode with an RS-422 interface and repeatedly transmits a 4-word test payload. It is designed to work as the transmitting half of a two-application pair — run the SER Async Recv sample on a separate channel to receive the transmitted data.

This sample supports SER module types including SC1-SC7 and newer SER variants. The transmit channel is hard-coded to channel 1, matching the receive channel of the companion application (hard-coded to channel 2). A physical RS-422 connection between channels 1 and 2 is required.

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

Prerequisites

Before running this sample, make sure you have:

  • An NAI board with a SER module installed (SC1-SC7 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.

  • A physical RS-422 cable connecting channel 1 to channel 2 on the SER module.

How to Run

Launch the ser_async_xmit executable from your build output directory. On startup the application looks for a configuration file (default_SerAsync_Tx.txt). Once connected, the application configures channel 1 for RS-422 async transmission and enters a transmit loop.

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_ASync_Tx(cardIndex, module) to configure channel 1 and begin transmitting.

#ifdef NAIBSP_CONFIG_SOFTWARE_OS_VXWORKS
int32_t SER_ASync_Tx_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_ASync_Tx(cardIndex, module);
               }
            }
         }

         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_ASync_Tx_Sample() on VxWorks.

Application Flow

  1. Reset channel 1 and clear both FIFOs.

  2. Configure channel 1 for async RS-422 transmission (9600 baud, 8N1, no parity).

  3. Build a 4-word test payload.

  4. Enter a transmit loop: load the FIFO, initiate transmission, prompt to repeat or quit.

Channel Configuration

The application hard-codes the transmit channel to channel 1 and configures it for async RS-422:

chanNum = 1;

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

check_status(naibrd_SER_SetCommProtocol(cardIndex, module, chanNum, NAIBRD_SER_PROTOCOL_ASYNC));
check_status(naibrd_SER_SetInterface(cardIndex, module, chanNum, NAIBRD_SER_INTF_RS422));
check_status(naibrd_SER_SetParityType(cardIndex, module, chanNum, NAIBRD_SER_PARITY_NONE));
check_status(naibrd_SER_SetNumDataBits(cardIndex, module, chanNum, NAIBRD_SER_DATA_BITS_8));
check_status(naibrd_SER_SetNumStopBits(cardIndex, module, chanNum, NAIBRD_SER_STOP_BITS_1));
check_status(naibrd_SER_SetBaudrate(cardIndex, module, chanNum, 9600));

Note that the receiver is not enabled on the transmit channel because this application only transmits — the companion receive application handles reception on channel 2.

Data Transmission Loop

The application builds a 4-word payload with incremental values starting at 0x31, then enters a loop that transmits the data each time the user presses Enter:

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

naibrd_msDelay(100);

do
{
   naiif_printf("Sending %d words ...", numWordsToSend);

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

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

   naiif_printf("Press ENTER to transmit again, or '%c' to exit program : ", NAI_QUIT_CHAR);
   bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
} while ( NAI_TRUE != bQuit );

The two-step transmit model (load then initiate) is standard for SSK 2.x. Data does not leave the FIFO until naibrd_SER_TransmitInitiate() is called.

Troubleshooting Reference

Error / Symptom Possible Causes Suggested Resolution

No board found or connection timeout

Board not powered, incorrect configuration file, network issue

Verify hardware is powered and connected.

Data not received by companion application

Cable not connected, baud rate mismatch, wrong channels

Verify RS-422 cable between channels 1 and 2. Ensure both applications use 9600 baud, 8N1.

FIFO overflow

Payload exceeds FIFO depth

Check the return value of naibrd_SER_LoadBufferWithTimeOut32().

Data sits in FIFO, never transmits

naibrd_SER_TransmitInitiate() not called

SSK 2.x requires an explicit transmit initiate after loading the FIFO.

Module not present at selected slot

No SER module installed

Verify hardware configuration.

Invalid baud rate

Module does not support the requested baud rate

Consult the SC3 Manual for supported baud rates.

Full Source

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

Full Source — ser_async_xmit.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_Tx.txt";

/* Function prototypes */
void Run_SER_ASync_Tx(int32_t cardIndex, int32_t module);

#define NUM_DATA_TX  4              /* Number of words to transmit */

/**************************************************************************************************************/
/** \defgroup SERAsyncTx

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

The Serial Asynchronous Transmit sample application illustrates the methods to call in the naibrd library to configure a given serial
channel for transmitting RS422. The \ref SERAsyncRx application can be run in unison with this application to transmit data.

\note A physical RS-422 connection between channel 1 and channel 2 is required for data transmission.

The main steps include:
- Querying the user for the card index and module number.
- Configuring the serial channel for asynchronous communication with RS422.
- Transmitting data through the serial channel.
- Displaying the transmitted data.
*/
/**************************************************************************************************************/
#ifdef NAIBSP_CONFIG_SOFTWARE_OS_VXWORKS
int32_t SER_ASync_Tx_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_Tx(cardIndex, module);
               }
            }
         }

         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 SERAsyncTx
Configures a serial module for asynchronous transmitting. The transmitting channel is hard-coded to channel #1.
\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]).
*/
/**************************************************************************************************************/
void Run_SER_ASync_Tx(int32_t cardIndex, int32_t module)
{
   int32_t chanNum;
   uint32_t SendData[NUM_DATA_TX];
   bool_t bQuit = NAI_FALSE;
   int32_t numWordsToSend = 0;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

   /* channelCount = naibrd_SER_GetChannelCount(moduleID); */
   /* naiapp_query_ChannelNumber(channelCount, 1, &chanNum); */
   /* Hard code TX channel to ch 1 */
   chanNum = 1;

   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_RS422));          /* RS422       */
   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 Bits */
   check_status(naibrd_SER_SetBaudrate(cardIndex, module, chanNum, 9600));                            /* 9600 baud   */

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

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

   /* Transmit data */
   do
   {
      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));

      /* 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);

      naiif_printf("Press ENTER to transmit 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