SER ASync Tx
Edit this on GitLab
SER ASync Tx
Explanation
ABOUT THIS SAMPLE CODE
This C program is designed for interacting with embedded function modules from North Atlantic Industries (NAI) using their Software Support Kit (SSK). It demonstrates how to configure and transmit data asynchronously via RS422 on a serial channel.
OVERVIEW
The application’s main objective is to guide users through configuring a serial channel and transmitting data using a loop-back interface. The application continuously prompts users for input until they decide to quit.
INCLUDED FILES AND LIBRARIES
The program includes several standard libraries for general-purpose functions (stdio.h
, stdlib.h
, string.h
, time.h
, ctype.h
), as well as NAI-specific header files for board and module access, queries, and utilities.
-
naiapp_boardaccess_menu.h
-
naiapp_boardaccess_query.h
-
naiapp_boardaccess_access.h
-
naiapp_boardaccess_display.h
-
naiapp_boardaccess_utils.h
-
nai.h
-
naibrd.h
-
naibrd_ser.h
-
nai_ether_adv.h
In addition to these header files, a configuration file named default_SerASync_Tx.txt
is set as a constant.
FUNCTIONS
-
Run_SER_ASync_Tx: Configures a serial module for asynchronous transmission and transmits data on a selected channel.
c void Run_SER_ASync_Tx(int32_t cardIndex, int3232 module, uint32_t moduleID);
DEFINITIONS AND CONSTANTS
-
CONFIG_FILE: Default configuration file for the sample application.
-
NUM_DATA_TX: Number of data words to be transmitted in each run.
-
MAX_TIMEOUT: Defines a max timeout of 10 milliseconds.
-
CLEAR_FIFO_TIMEOUT: Sets a timeout for clearing FIFOs to 1 second (1000 milliseconds).
MAIN FUNCTION
int32_t main(void);
The main
function initializes the application, queries user input for card index and module number, and repeatedly transmits data until the user chooses to quit.
WORKFLOW DESCRIPTION
-
Configuration and Initialization:
-
The program initializes the user interface by calling
naiapp_RunBoardMenu
with theCONFIG_FILE
.
-
-
User Input for Card and Module:
-
Queries the user for the card index.
-
Queries the user for the module number.
-
-
Transmit Data:
-
The
Run_SER_ASync_Tx
function configures and transmits data asynchronously on the chosen serial channel.
-
-
Query for Quit:
-
After each transmission, the program prompts the user to either quit the application or restart the transmission process.
-
-
Clean-Up:
-
Before exiting, it closes all open card connections by calling
naiapp_access_CloseAllOpenCards
.
-
FUNCTION DETAILS - Run_SER_ASync_Tx
This function handles channel selection, configuration, and data transmission:
-
Channel Selection:
-
Queries the number of channels available using
naibrd_SER_GetChannelCount
and queries for a specific channel number.
-
-
Channel Reset and FIFO Clear:
-
Resets the selected channel and clears the receive and transmit FIFOs.
-
-
Channel Configuration:
-
Sets protocol to asynchronous, interface level to loopback, parity to none, 8 data bits, 1 stop bit, and baud rate to 9600.
-
-
Data Preparation:
-
Prepares the data to be transmitted (
SendData
) and calculates the number of words.
-
-
Transmission Process:
-
Loads the data into the transmit FIFO and initiates the transmission.
-
Prompts the user to either transmit again or exit.
-
The entire process is captured within a loop that continues until the user explicitly chooses to quit.
ENUMERATIONS AND CONSTANTS USED
-
NAI_SER_CTRLLO_CLEAR_RX_FIFO: Constant for control register to clear RX FIFO.
-
NAI_SER_CTRLLO_CLEAR_TX_FIFO: Constant for control register to clear TX FIFO.
-
NAI_SER_PROTOCOL_ASYNC: Enumeration for setting the serial communication protocol to asynchronous.
-
NAI_SER_INTF_LOOPBACK: Sets the interface level to loopback for testing.
-
NAI_SER_PARITY_NONE: Sets parity to none.
-
NAI_QUIT_CHAR: Character used to signal program termination.
CONCLUSION
This sample code serves to assist developers in configuring and utilizing NAI embedded function modules for asynchronous serial communication. By following the included prompts and configuration steps, users can successfully transmit data over a serial channel in a loop-back setup.
#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_Tx.txt";
/* Function prototypes */
void Run_SER_ASync_Tx(int32_t cardIndex, int32_t module, uint32_t moduleID);
#define NUM_DATA_TX 4
#define MAX_TIMEOUT 10 /* 10ms timeout */
#define CLEAR_FIFO_TIMEOUT 1000 /* 1 second */
/**************************************************************************************************************/
/** \defgroup SERAsyncTx Serial Asynchronous Transmit
The purpose of the Serial Asynchronous Transmit sample application is to illustrate the methods to call in the
naibrd library to configure a given serial channel for transmitting RS422. The application will write data to the
selected serial channel's transmit buffer and transmit it
*/
/**************************************************************************************************************/
#if defined (__VXWORKS__)
int32_t SER_ASync_Tx_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 the user for the card index */
stop = naiapp_query_CardIndex(naiapp_GetBoardCnt(), 0, &cardIndex);
if (stop != TRUE)
{
check_status(naibrd_GetModuleCount(cardIndex, &moduleCnt));
/* Query the 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_Tx(cardIndex, module, moduleID);
}
}
}
printf("\nType Q to quit or Enter key to restart application:\n");
stop = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
}
}
printf("\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 user is queried for the serial channel to transmit 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_Tx(int32_t cardIndex, int32_t module, uint32_t moduleID)
{
int32_t chanNum, channelCount;
int32_t nCntlValueLo;
int32_t ch, i;
uint32_t SendData[NUM_DATA_TX];
bool_t bQuit = FALSE;
uint32_t nNumWordsSend = 0;
int8_t inputBuffer[80];
int32_t inputResponseCnt;
channelCount = naibrd_SER_GetChannelCount(moduleID);
check_status(naiapp_query_ChannelNumber(channelCount, 1, &chanNum));
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, NAI_SER_INTF_LOOPBACK)); /* LoopBack */
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 */
for (nNumWordsSend = 0; nNumWordsSend < NUM_DATA_TX; nNumWordsSend++)
{
SendData[nNumWordsSend] = (uint8_t)(nNumWordsSend + 0x31); /* incremental data */
printf("data[%i] = 0x%X\n", nNumWordsSend, SendData[nNumWordsSend]);
}
/* Add a delay here for the configuration to be ready */
nai_msDelay(500);
do
{
printf("Sending %d words ...", nNumWordsSend);
naibrd_SER_TransmitBuffer(cardIndex, module, chanNum, sizeof(SendData[0]), SendData, nNumWordsSend, (uint32_t*)&nNumWordsSend); /* load FIFO */
naibrd_SER_TransmitInitiate(cardIndex, module, chanNum); /* Initiate Transmit */
printf(" %d words sent\n", nNumWordsSend);
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 (TRUE != bQuit);
return;
}