M1553 RT HBuff
Edit this on GitLab
M1553 RT HBuff
Explanation
About the Sample Application Code for NAI 1553 Function Modules
This application code demonstrates how to interact with North Atlantic Industries (NAI) embedded function modules, specifically focusing on configuring and utilizing a 1553 channel as a Remote Terminal (RT). The following outlines key components, functions, and the general workflow of the application.
Code Overview and Structure
Header Files
- C Standard Libraries: Includes standard libraries for I/O operations, memory management, string manipulation, and time handling.
c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
-
NAI Application Libraries: These include various headers from the NAI software support kit (SSK), which provides functions for board access, querying, display, and utilities.
c #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"
-
1553 Specific Utilities: These provide specific functions needed to interact with 1553 modules.
c #include "nai_1553_utils.h"
-
NAI Board and Module Headers: Include header files for accessing functions directly related to the NAI board and its modules.
c #include "nai.h" #include "naibrd.h" #include "functions/naibrd_1553.h"
Constants and Global Variables
- Configuration File: Specifies the configuration file to be used.
c
static const int8_t *CONFIG_FILE = (int8_t *)"default_1553_RT_HBuff.txt";
-
Data Block Identifiers and Default Values: Define constants for data block IDs and default values for various parameters. ```c static const uint16_t DATA_BLOCK_ID_TX1 = 1; static const uint16_t DATA_BLOCK_ID_TX2 = 2; static const uint16_t DATA_BLOCK_ID_RX = 3;
static const int32_t DEF_RT_CHANNEL = 1; static const int16_t DEF_RT_DEV_NUM = 1; static const uint8_t DEF_RT_ADDRESS = 1; static const uint8_t DEF_RT_SUBADDR = 2; static const uint16_t DEF_RT_RX_BUF_TYPE = NAI_1553_RT_DATABLOCK_DOUBLE; static const uint16_t RTBC_WORDCNT = 32; ```
-
Global Variables: Hold the current data block identifier.
c static int32_t currDataBlock;
Function Prototypes These prototypes define the functions used in the application for getting decoded messages, updating transmitter data blocks and buffers, and processing messages.
static bool_t GetRTHBufDecodedMsgs(int32_t cardIndex, int32_t module, uint32_t modid);
static int32_t UpdateTxDataBlock(uint16_t DevNum, uint8_t Subaddress);
static int32_t UpdateTxBuffer(uint16_t DevNum, uint16_t nDataBlkID);
static int32_t ProcessMessages(uint16_t DevNum, uint8_t Subaddress, int32_t duration);
Main Function
Workflow
1. Initialization: Define control variables and input buffers.
c
bool_t stop = FALSE;
int32_t cardIndex;
int32_t moduleCnt;
int32_t module;
uint32_t moduleID = 0;
int8_t inputBuffer[80];
int32_t inputResponseCnt;
-
Run Configuration Menu: Load the configuration file and run the board menu. ```c if (naiapp_RunBoardMenu(CONFIG_FILE) == TRUE) { while (stop != TRUE) { // Interact with the user to get card index and module number // … code block
if ((moduleID != 0)) { // Fetch decoded messages GetRTHBufDecodedMsgs(cardIndex, module, moduleID); } } } ```
-
User Interaction Loop: Loop to interact with the user, allowing them to restart or quit the application.
c printf("\nType Q to quit or Enter key to restart application:\n"); stop = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
-
Cleanup and Exit: Close any open cards before exiting the program. ```c printf("\nType the Enter key to exit the program: "); naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt); naiapp_access_CloseAllOpenCards();
return 0; ```
Supporting Functions Each function plays a specific role in the operation of the Remote Terminal.
GetRTHBufDecodedMsgs
- Purpose: Configure and start the RT, creating and mapping data blocks to subaddresses, then handle received messages.
c
static bool_t GetRTHBufDecodedMsgs(int32_t cardIndex, int32_t module, uint32_t modid);
UpdateTxDataBlock
- Purpose: Alternates the Tx data buffer, updating it periodically.
c
static int32_t UpdateTxDataBlock(uint16_t DevNum, uint8_t Subaddress);
UpdateTxBuffer
- Purpose: Writes new data into the specified Tx buffer.
c
static int32_t UpdateTxBuffer(uint16_t DevNum, uint16_t nDataBlkID);
ProcessMessages
- Purpose: Handles Rx and Tx messages, updating Tx data blocks, and displaying received message data.
c
static int32_t ProcessMessages(uint16_t DevNum, uint8_t Subaddress, int32_t duration);
Conclusion This application code serves as a comprehensive example of configuring and using a 1553 channel as a Remote Terminal with NAI’s function modules. It demonstrates setting up Host Buffers, mapping data blocks, interacting with the user, and handling received and transmitted messages. This document provides a clear understanding of the application’s structure and workflow, helping users effectively utilize the provided code.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.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"
/* Common 1553 Sample Program include files */
#include "nai_1553_utils.h"
/* naibrd include files */
#include "nai.h"
#include "naibrd.h"
#include "functions/naibrd_1553.h"
static const int8_t *CONFIG_FILE = (int8_t *)"default_1553_RT_HBuff.txt";
/* Function prototypes */
static bool_t GetRTHBufDecodedMsgs(int32_t cardIndex, int32_t module, uint32_t modid);
static int32_t UpdateTxDataBlock(uint16_t DevNum, uint8_t Subaddress);
static int32_t UpdateTxBuffer(uint16_t DevNum, uint16_t nDataBlkID);
static int32_t ProcessMessages(uint16_t DevNum, uint8_t Subaddress, int32_t duration);
static const uint16_t DATA_BLOCK_ID_TX1 = 1;
static const uint16_t DATA_BLOCK_ID_TX2 = 2;
static const uint16_t DATA_BLOCK_ID_RX = 3;
static const int32_t DEF_RT_CHANNEL = 1;
static const int16_t DEF_RT_DEV_NUM = 1;
static const uint8_t DEF_RT_ADDRESS = 1;
static const uint8_t DEF_RT_SUBADDR = 2;
static const uint16_t DEF_RT_RX_BUF_TYPE = NAI_1553_RT_DATABLOCK_DOUBLE;
static const uint16_t RTBC_WORDCNT = 32;
/* Global Variables */
static int32_t currDataBlock;
/**************************************************************************************************************/
/**
<summary>
The purpose of the M1553_RT_HBuff is to illustrate the methods to call in the naibrd library to configure the 1553 channel as a
Remote Terminal, utilize Rt Host Buffers, legalize Subaddress 2 for both Tx and Rx, and set it up to receive data
using an Rx double buffer and transmit data from two alternating Tx buffers (active and inactive). If a Rx message
is received, the received data will be displayed. If a Rx message is received, the received data will be data will be displayed.
If a Tx message is received, the data in the active tx buffer will be copied over from the Rt stack to the Host Buffer, and the data will be
sent to the bus. While the RT is running, Tx buffer data will be updated periodically via the Rt stack to Host Buffer copy operation. The
use of the following Host Buffer functions will be demonstrated:
naibrd_1553_RtStkToHbuf32
naibrd_1553_RTGetHBufMsgCount
naibrd_1553_RtGetHBufMsgDecoded
The following system configuration routines from the nai_sys_cfg.c file are called to assist with the configuration
setup for this program prior to calling the naibrd 1553 routines.
- ConfigDevice
- DisplayDeviceCfg
- GetBoardSNModCfg
- CheckModule
</summary>
*/
/**************************************************************************************************************/
#if defined (__VXWORKS__)
int32_t M1553_RT_HBuff(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))
{
GetRTHBufDecodedMsgs(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;
}
static bool_t GetRTHBufDecodedMsgs(int32_t cardIndex, int32_t module, uint32_t modid)
{
/* Variables */
bool_t bQuit = FALSE;
int32_t rtchan;
uint8_t rtaddr;
uint8_t sa = DEF_RT_SUBADDR;
int16_t DevNum = 0;
int32_t swResult;
uint16_t nDataBlockType = 0;
bool_t bContinue = TRUE;
int32_t duration;
bool_t bSoftwareRTAddr;
int8_t inputBuffer[80];
int32_t inputResponseCnt;
/* Get Card, Module, Channel Numbers and Open a Handle */
bQuit = Get1553RTCfg(modid, DEF_RT_CHANNEL, DEF_RT_ADDRESS, &rtchan, &rtaddr);
if (bQuit)
{
return bQuit;
}
printf("Enter Subaddress\n");
bQuit = Get1553Address(31, DEF_RT_SUBADDR, &sa);
/* Get Logical Device # */
bQuit = Get1553LogicalDevNum(DEF_RT_DEV_NUM, &DevNum);
if (bQuit)
{
return bQuit;
}
/* Associate Card, Module and Channel Numbers with the Logical Device # */
swResult = naibrd_1553_Open(cardIndex, module, rtchan, DevNum);
if (swResult)
{
bQuit = TRUE;
printf("Error: naibrd_1553_Open %d", swResult);
return bQuit;
}
/* Initialize Device */
swResult = naibrd_1553_Initialize(DevNum, NAI_1553_ACCESS_CARD, NAI_1553_MODE_RT, 0, 0, 0);
if (swResult != 0)
{
bQuit = TRUE;
printf("Error: naibrd_1553_Initialize %d", swResult);
return bQuit;
}
/* Get RT Address Source from user */
bQuit = Get1553RTAddressSource(TRUE, &bSoftwareRTAddr);
if (bQuit)
{
return bQuit;
}
if (bSoftwareRTAddr)
{
/* Set RTAD_SW_EN and RT_ADR_LAT in software */
swResult = naibrd_1553_WriteAuxReg(DevNum, 0x2, 0x0018);
/* Set RT address */
swResult = naibrd_1553_RtSetAddress(DevNum, rtaddr);
if (swResult != 0)
{
bQuit = TRUE;
printf("Error: naibrd_1553_RtSetAddress %d", swResult);
return bQuit;
}
}
else
{
/* Unset RTAD_SW_EN and set RT_ADR_LAT in software */
swResult = naibrd_1553_WriteAuxReg(DevNum, 0x2, 0x0008);
}
if (modid == NAI_MODULE_ID_FT8)
{
/* Simplex Enable (for internal NAI testing only, do not enable) */
//naibrd_1553_WriteAuxReg(DevNum, 0x3, 0x4000);
//naibrd_1553_WriteAuxReg(DevNum, 0xF, 0x1);
}
/* Select Single Buffer, Double Buffer or Circular Buffer for Rx Messages */
bQuit = Get1553RxBufferType(DEF_RT_RX_BUF_TYPE, &nDataBlockType);
if (bQuit)
{
return bQuit;
}
/* Create a Rx Buffer data block and map to the desired subaddress */
swResult = naibrd_1553_RtDataBlockCreate(DevNum, DATA_BLOCK_ID_RX, nDataBlockType, NULL, 0);
if (swResult != 0)
{
bQuit = TRUE;
printf("Error: naibrd_1553_RtDataBlockCreate %d", swResult);
return bQuit;
}
swResult = naibrd_1553_RtDataBlockMapToSubaddress(DevNum, DATA_BLOCK_ID_RX, sa, NAI_1553_RT_MESSAGE_TYPE_RX, 0, 1);
if (swResult != 0)
{
bQuit = TRUE;
printf("Error: naibrd_1553_RtDataBlockMapToSubaddress %d", swResult);
return bQuit;
}
/* Create two Tx Buffer data blocks and map the first to the desired subaddress */
swResult = naibrd_1553_RtDataBlockCreate(DevNum, DATA_BLOCK_ID_TX1, NAI_1553_RT_DATABLOCK_SINGLE_32, NULL, 0);
if (swResult != 0)
{
bQuit = TRUE;
printf("Error: naibrd_1553_RtDataBlockCreate %d", swResult);
return bQuit;
}
swResult = naibrd_1553_RtDataBlockCreate(DevNum, DATA_BLOCK_ID_TX2, NAI_1553_RT_DATABLOCK_SINGLE_32, NULL, 0);
if (swResult != 0)
{
bQuit = TRUE;
printf("Error: naibrd_1553_RtDataBlockCreate %d", swResult);
return bQuit;
}
swResult = naibrd_1553_RtDataBlockMapToSubaddress(DevNum, DATA_BLOCK_ID_TX1, sa, NAI_1553_RT_MESSAGE_TYPE_TX, 0, 1);
if (swResult < 0)
{
bQuit = TRUE;
printf("Error: naibrd_1553_RtDataBlockMapToSubaddress %d", swResult);
return bQuit;
}
currDataBlock = DATA_BLOCK_ID_TX1;
while (bContinue)
{
printf("\nType duration (in seconds) to run RT or %c to quit (default: 5) : ", NAI_QUIT_CHAR);
bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
if (!bQuit)
{
duration = 5;
if (inputResponseCnt > 0)
{
duration = (int)atol((const char*)inputBuffer);
}
/* Create Host Buffer */
swResult = naibrd_1553_RtHbuffInstall(DevNum, NAI_1553_MAX_SIZE_OF_HOST_BUFFER);
if (swResult != 0)
{
bQuit = TRUE;
printf("Error: naibrd_1553_RtHbuffInstall %d", swResult);
return bQuit;
}
/* Start RT */
swResult = naibrd_1553_RtStart(DevNum);
if (swResult != 0)
{
bQuit = TRUE;
printf("Error: naibrd_1553_RtStart %d", swResult);
return bQuit;
}
/* Process New Messages */
ProcessMessages(DevNum, sa, duration);
/* Stop RT */
swResult = naibrd_1553_RtStop(DevNum);
if (swResult != 0)
{
bQuit = TRUE;
printf("Error: naibrd_1553_RtStop %d", swResult);
return bQuit;
}
}
else
bContinue = FALSE;
}
swResult = naibrd_1553_RtHbuffUnInstall(DevNum);
if (swResult != 0)
{
bQuit = TRUE;
printf("Error: naibrd_1553_RtHbuffUnInstall %d", swResult);
return bQuit;
}
/* Free 1553 Device */
swResult = naibrd_1553_Free(DevNum);
if (swResult != 0)
{
bQuit = TRUE;
printf("Error: naibrd_1553_Free %d", swResult);
return bQuit;
}
return bQuit;
}
static int32_t UpdateTxDataBlock(uint16_t DevNum, uint8_t Subaddress)
{
/* Update Data in TX Data Block */
if (currDataBlock == DATA_BLOCK_ID_TX1)
{
UpdateTxBuffer(DevNum, DATA_BLOCK_ID_TX2);
/* Change data pointer to block 2 */
naibrd_1553_RtTxDataBlockSwap(DevNum, DATA_BLOCK_ID_TX2, Subaddress);
currDataBlock = DATA_BLOCK_ID_TX2;
}
else
{
UpdateTxBuffer(DevNum, DATA_BLOCK_ID_TX1);
/* Change data pointer to block 1 */
naibrd_1553_RtTxDataBlockSwap(DevNum, DATA_BLOCK_ID_TX1, Subaddress);
currDataBlock = DATA_BLOCK_ID_TX1;
}
return 0;
}
static int ProcessMessages(uint16_t DevNum, uint8_t Subaddress, int32_t duration)
{
time_t end, period;
uint32_t swResult;
int32_t i;
uint32_t dwStkLost = 0;
uint32_t dwHBufLost = 0;
uint32_t dwMsgCount = 0;
uint32_t dwMsgCountGet = 0;
uint32_t dwCurCount = 0;
int32_t count = 0;
naiDecodedMessageStructure sMsg;
end = time(NULL) + duration;
period = time(NULL) + 1;
while (time(NULL) < end)
{
/* Update Tx Data Block periodically */
if (time(NULL) > period)
{
UpdateTxDataBlock(DevNum, Subaddress);
period = time(NULL) + 1;
}
/* Update message count */
swResult = naibrd_1553_RtStkToHbuf32(DevNum);
if (swResult < 0)
{
printf("Error: naibrd_1553_RtStkToHbuf32 %d\n\n", swResult);
return 0;
}
/* get message count */
dwMsgCountGet = naibrd_1553_RTGetHBufMsgCount(DevNum);
if (dwMsgCountGet >= 1)
{
/* Decode Raw Message */
swResult = naibrd_1553_RtGetHBufMsgDecoded(DevNum, &sMsg, &dwMsgCount, &dwStkLost, &dwHBufLost, NAI_1553_RT_MESSAGE_LOC_NEXT_PURGE);
if (swResult < 0)
{
printf("Error: naibrd_1553_RtGetHBufMsgDecoded %d\n\n", swResult);
return 0;
}
/* Message Lost */
if ((dwStkLost > 0) || (dwHBufLost > 0))
{
printf("Number of msgs lost %d\n", (int)(dwStkLost + dwHBufLost));
}
/* Message Found */
if (dwMsgCount)
{
++dwCurCount;
if ((sMsg.wCommandWord1 & 0x0400) != 0x0400) /* If this is a Rx message */
{
printf("Rx Msg Received\n");
printf("\n\nDecoded Message:\n\n");
printf("Block Status - 0x%04X\n", sMsg.wBlockStatus);
printf("Time Tag - 0x%04X\n", sMsg.wTimeTag);
printf("Command Word - 0x%04X\n", sMsg.wCommandWord1);
printf("Data Word Count - 0x%04X\n", sMsg.wDataWordCount);
printf("Data:");
for (i = 0; i < sMsg.wDataWordCount; i++)
{
if (i % 8 == 0)
{
printf("\n");
}
printf("0x%04X ", sMsg.waData[i]);
}
printf("count: %d\n", count++);
printf("\n\n");
}
else
{
printf("Tx Msg Received\n");
printf("\n\nDecoded Message:\n\n");
printf("Block Status - 0x%04X\n", sMsg.wBlockStatus);
printf("Time Tag - 0x%04X\n", sMsg.wTimeTag);
printf("Command Word - 0x%04X\n", sMsg.wCommandWord1);
printf("Data Word Count - 0x%04X\n", sMsg.wDataWordCount);
printf("count: %d\n", count++);
printf("\n\n");
}
}
}
nai_msDelay(10);
}
return 1;
}
static int32_t UpdateTxBuffer(uint16_t DevNum, uint16_t nDataBlkID)
{
static uint16_t wBuffer[32] = { 0x0000 };
uint16_t i = 0x0000;
uint32_t swResult;
/* Increment Tx buffer data */
for (i = 0; i < 32; i++)
{
wBuffer[i] += 1;
}
/* Write new data to Tx buffer */
swResult = naibrd_1553_RtDataBlockWrite(DevNum, nDataBlkID, wBuffer, RTBC_WORDCNT, 0);
if (swResult < 0)
{
printf("Error: naibrd_1553_RtDataBlockWrite %d\n\n", swResult);
return 0;
}
else
{
printf("New data written to Tx Buffer\n\n");
}
return 1;
}