SER HDLC Tx
Edit this on GitLab
SER HDLC Tx
Explanation
About This Code
This C code provides a sample application for serial synchronous transmission using North Atlantic Industries� (NAI) Serial HDLC function module. It demonstrates how to configure a serial channel for transmitting data using the 'naibrd' library.
Key Components and Definitions
-
Header Files:
-
Standard Libraries: 'stdio.h', 'stdlib.h', 'string.h', 'time.h', 'ctype.h'.
-
Common Sample Program: Provides common functionalities like menu handling and display functions.
-
'naiapp_boardaccess_menu.h'
-
'naiapp_boardaccess_query.h'
-
'naiapp_boardaccess_access.h'
-
'naiapp_boardaccess_display.h'
-
'naiapp_boardaccess_utils.h'
-
NAI Libraries: Pertains to NAI-specific hardware and functionalities.
-
'nai.h'
-
'naibrd.h'
-
'naibrd_ser.h' (deals with serial module functions)
-
'nai_ether_adv.h' (advanced Ethernet configurations)
-
-
Constants and Definitions:
-
'CONFIG_FILE': Defines a configuration file '"default_SerHDLC_Tx.txt"'.
-
'NUM_DATA_TX': Number of data words to transmit (4).
-
'MAX_TIMEOUT': Maximum timeout in milliseconds (10ms).
-
'CLEAR_FIFO_TIMEOUT': Timeout for clearing FIFO (1 second or 1000ms).
-
-
Function Prototypes:
-
'Run_SER_HDLC_Tx': Function to run the serial HDLC transmission with specified parameters.
-
Main Application Breakdown
Main Entry Point '''c #if defined (VXWORKS) int32_t SER_HDLC_Tx_Sample(void) #else int32_t main(void) #endif ''' The entry point varies based on the operating system. For VXWORKS, it uses 'SER_HDLC_Tx_Sample'; otherwise, it uses 'main'.
Initialization and Main Loop '''c bool_t stop = FALSE; int32_t cardIndex, moduleCnt, module; uint32_t moduleID = 0; int8_t inputBuffer[80]; int32_t inputResponseCnt; ''' - Board Menu: The application starts by running a board menu using 'naiapp_RunBoardMenu(CONFIG_FILE)'. - Loop: Continuously prompts the user unless the exit condition ('stop' becomes 'TRUE') is met.
*Query and Configuration * - Card Index: User is queried for the card index using 'naiapp_query_CardIndex'. - Module Number: Once a valid card index is obtained, the user is queried for the module number using 'naiapp_query_ModuleNumber'. - Module ID: Retrieves the module ID using 'naibrd_GetModuleID'. - Transmission Run: If a valid module ID is obtained, 'Run_SER_HDLC_Tx' is called with the card index, module number, and module ID.
Exit Handling '''c printf("\nType the Enter key to exit the program: "); naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt); naiapp_access_CloseAllOpenCards(); ''' Prompts the user to exit and closes all open connections.
Function 'Run_SER_HDLC_Tx': Serial HDLC Transmission '''c void Run_SER_HDLC_Tx(int32_t cardIndex, int32_t modNum, uint32_t modid) ''' This function configures and transmits data on a specified serial module channel.
Channel Configuration Steps 1. Channel Count: Retrieves the number of channels using 'naibrd_SER_GetChannelCount'. 2. Channel Number: Queries the user for the channel number using 'naiapp_query_ChannelNumber'.
FIFO Operations 1. FIFO Reset and Clear: Resets and clears both Rx and Tx FIFOs. 2. Waiting for FIFO Clearance: Waits (with timeout) for FIFO to clear completely.
Configuration Parameters 1. Protocol: Sets HDLC protocol using 'naibrd_SER_SetProtocol'. 2. Interface Level: Sets interface to RS422 using 'naibrd_SER_SetInterfaceLevel'. 3. Clock Mode: Uses internal clock for transmission and reception. 4. Baudrate: Sets the baud rate to 115200 using 'naibrd_SER_SetBaudrate'. 5. Sync Character: Sets HDLC address and sync character. 6. Config Word: Sets the configuration word for 16-bit HDLC address recognition.
Data Transmission 1. Data Preparation: Prepares the data to be sent in an incremental pattern. 2. Transmission Loop: Continuously sends data until the user decides to quit ('bQuit' becomes 'TRUE').
Exit Condition '''c 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); ''' Prompts the user to either continue or quit.
Summary The application effectively demonstrates the initialization, configuration, and data transmission using NAI’s Serial HDLC function module. It provides a clear example of how to use the 'naibrd' library to interact with and control NAI embedded modules for serial communication.
#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_SerHDLC_Tx.txt";
/* Function prototypes */
void Run_SER_HDLC_Tx(int32_t cardIndex, int32_t modNum, uint32_t modid);
#define NUM_DATA_TX 4
#define MAX_TIMEOUT 10 /* 10ms timeout */
#define CLEAR_FIFO_TIMEOUT 1000 /* 1 second */
/**************************************************************************************************************/
/** \defgroup SERHDLCTx Serial Synchronous Transmit
The purpose of the Serial Synchronous Transmit sample application is to illustrate the methods to call in the
naibrd library to configure a given serial channel for transmitting. The SER_HDLC_Rx application can be run in
unison to this application to receive serial data.
*/
/**************************************************************************************************************/
#if defined (__VXWORKS__)
int32_t SER_HDLC_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_HDLC_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 SERHDLCTx
Configures a serial module for synchronous 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 modNum (Input) Module Number of the module to access (1 - [max modules for board]).
\param modid (Input) The ID of the module.
*/
/**************************************************************************************************************/
void Run_SER_HDLC_Tx(int32_t cardIndex, int32_t modNum, uint32_t modid)
{
int32_t ch, i;
int32_t channelCount;
int32_t chanNum;
int32_t nCntlValueLo, nConfigWordLo;
int32_t nNumWordsSend = 0;
bool_t bQuit = FALSE;
uint32_t SendData[NUM_DATA_TX];
int8_t inputBuffer[80];
int32_t inputResponseCnt;
channelCount = naibrd_SER_GetChannelCount(modid);
naiapp_query_ChannelNumber(channelCount, 1, &chanNum);
naibrd_SER_ChannelReset(cardIndex, modNum, chanNum);
naibrd_SER_ClearRxFifo(cardIndex, modNum, chanNum);
naibrd_SER_ClearTxFifo(cardIndex, modNum, 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, modNum, 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 HDLC on the channel selected. */
check_status(naibrd_SER_SetProtocol(cardIndex, modNum, chanNum, NAI_SER_PROTOCOL_HDLC)); /* HDLC mode */
check_status(naibrd_SER_SetInterfaceLevel(cardIndex, modNum, chanNum, NAI_SER_INTF_RS422)); /* RS422 */
check_status(naibrd_SER_SetClockMode(cardIndex, modNum, chanNum, TXINT_RXINT)); /* Tx and Rx internal clock */
check_status(naibrd_SER_SetBaudrate(cardIndex, modNum, chanNum, 115200)); /* 115,200b */
check_status(naibrd_SER_SetTxHdlcAddrsSyncChar(cardIndex, modNum, chanNum, 0x247A)); /* xmit sync char - must be same as recv for loopback */
nConfigWordLo = (NAI_SER_CFGLO_ADDR_LEN_16 | NAI_SER_CFGLO_ADDR_REC); /* 16-bit HDLC addr recognition */
check_status(naibrd_SER_SetChannelConfigRaw(cardIndex, modNum, chanNum, nConfigWordLo));
/* 100 millisecond wait for initialization to complete */
nai_msDelay(100);
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]);
}
do
{
printf("Sending %d words ...", nNumWordsSend);
naibrd_SER_TransmitBuffer(cardIndex, modNum, chanNum, sizeof(SendData[0]), SendData, nNumWordsSend, (uint32_t*)&nNumWordsSend); /* load FIFO */
naibrd_SER_TransmitInitiate(cardIndex, modNum, 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;
}