SER Async Xmit
Edit this on GitLab
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.
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_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:
|
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 |
Data sits in FIFO, never transmits |
|
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;
}