SUM1553 RT ProcCtrl
Edit this on GitLab
SUM1553 RT Processor Control Sample Application (SSK 1.x)
Overview
The SUM1553 RT Processor Control sample application demonstrates how to configure a SUMMIT 1553 channel as a Remote Terminal (RT) with the on-module 1553 processor enabled to handle message buffering and event notification using the NAI Software Support Kit (SSK 1.x). Instead of the host polling for new data (as in the RT Ping-Pong sample), this sample offloads message handling to the SUMMIT 1553 processor. When a BC-to-RT message arrives, the processor places it on an Event FIFO and triggers an interrupt. An Ethernet Interrupt Driven Reply (IDR) is configured so the board automatically sends the message data to the host over the network as an Unprompted Reply (UPR), eliminating the need for host-side polling entirely.
This sample configures the RT to:
-
Accept BC-to-RT (receive) messages on all subaddresses.
-
Respond to RT-to-BC (transmit) requests on all subaddresses.
-
Use ping-pong buffering for the underlying data blocks.
-
Enable the 1553 processor to capture received messages and place them on the Event FIFO.
-
Automatically deliver received messages to the host via Ethernet IDR when the processor generates an interrupt.
After configuration, the interactive loop lets you:
-
Enter a duration (seconds) — listen for IDR messages for the specified period and display received BC-to-RT data (default: 5 seconds).
-
Press 'U' — update the RT transmit data for subaddress 3 via the processor’s Request FIFO.
-
Press 'Q' — disable RT execution and exit.
|
Important
|
This sample uses the |
Supported Modules
This sample supports SUMMIT 1553 module types: N7, N8, NA, NB, and NC. The helper function IsSUMMIT1553(modid) is used at runtime to confirm that the selected module slot contains a supported SUMMIT 1553 device. Each SUMMIT 1553 module provides up to 2 channels.
|
Note
|
The SUM1553 RT Processor Control sample can run in conjunction with the SUM1553_BC_Scheduler companion sample to exercise BC and RT operations together on the same 1553 bus. |
Prerequisites
Before running this sample, make sure you have:
-
An NAI board with a SUMMIT 1553 module installed (N7, N8, NA, NB, or NC).
-
SSK 1.x installed on your development host.
-
The sample applications built. Refer to the SSK 1.x build instructions for your platform if you have not already compiled them.
-
An Ethernet connection to the board (required for the IDR mechanism). This sample requires Ethernet connectivity — PCI/cPCI connections do not support IDR.
-
A Bus Controller running on the same bus (for example, the SUM1553_BC_Scheduler sample) to send messages to this RT.
How to Run
Launch the SUM1553_RT_ProcCtrl executable from your build output directory. On startup the application looks for a configuration file (default_SUM1553_RTProc.txt). On the first run, this file will not exist — the application will present an interactive board menu where you configure a board connection, card index, and module slot. You can save this configuration so that subsequent runs skip the menu and connect automatically. Once connected, you select an RT channel and RT address, and the RT begins listening on the bus with processor control and IDR active.
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 SUMMIT 1553. |
The main() function follows a standard SSK 1.x startup flow:
-
Call
naiapp_RunBoardMenu()to load a saved configuration file (if one exists) or present the interactive board menu. The configuration file (default_SUM1553_RTProc.txt) is not included with the SSK — it is created when the user saves their connection settings from the board menu. On the first run, the menu will always appear. -
Query the user for a card index with
naiapp_query_CardIndex(). -
Query for a module slot with
naiapp_query_ModuleNumber(). -
Retrieve the module ID with
naibrd_GetModuleID()and pass it toRun_SUM1553_RT_ProcCtrl()for channel configuration.
#if defined (__VXWORKS__)
int32_t SUM1553_RT_ProcCtrl(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_SUM1553_RT_ProcCtrl(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;
}
|
Important
|
Common connection errors you may encounter at this stage:
|
Program Structure
Entry Point
The program entry point is main() on most platforms and SUM1553_RT_ProcCtrl() on VxWorks. Both follow the same logic: run the board menu, then loop over card/module selection until the user quits.
Module Detection
After the user selects a module slot, naibrd_GetModuleID() returns the module identifier. The helper IsSUMMIT1553(modid) (called inside Get1553RTCfg()) validates that the module is a supported SUMMIT 1553 type. SUMMIT 1553 modules provide up to 2 channels.
User Input Flow
The application walks the user through four selection steps before starting the RT:
-
Card index —
naiapp_query_CardIndex()prompts for the board to use. -
Module slot —
naiapp_query_ModuleNumber()prompts for the slot containing the SUMMIT 1553 module. -
RT channel —
Get1553RTCfg()prompts for the channel to configure as a Remote Terminal (default channel 1). -
RT address —
Get1553RTCfg()prompts for the RT bus address (default address 1, range 0—31).
Once the channel and address are selected, Run_SUM1553_RT_ProcCtrl() sets up Ethernet IDR, configures the RT with processor control, and enters the interactive loop.
Interactive Loop
After the RT starts, the hardware responds to BC messages autonomously. Received messages are delivered to the host via Ethernet IDR without any polling. The application enters an interactive loop where:
-
Enter (or numeric duration) — listens on the IDR socket for the specified number of seconds (default 5) and displays any messages received from the BC. Only messages with data that differs from the previous read are displayed.
-
'U' — increments a counter and submits an updated transmit data block for subaddress 3 via the processor’s Request FIFO.
-
'Q' — disables RT execution and returns to the card/module selection prompt.
Processor Control Architecture
The SUMMIT 1553 module contains an on-module processor that can manage RT buffer servicing and event generation independently of the host. When processor control is enabled, the data flow changes significantly compared to the Ping-Pong sample.
Data Flow: Processor Control vs. Ping-Pong
In the Ping-Pong approach (SUM1553_RT_PingPong), the host must:
-
Poll each subaddress control word for the BAC (Block Accessed) flag.
-
Read the data block when new data is detected.
-
Clear the BAC flag.
In the Processor Control approach (this sample):
-
The on-module processor monitors subaddress interrupts automatically.
-
When a BC-to-RT message arrives, the processor reads the data and places it on the Event FIFO.
-
The processor generates an interrupt, which triggers an Ethernet IDR message to the host.
-
The host receives the message data over Ethernet without any polling.
This makes processor control better suited for latency-sensitive or high-throughput applications where the host cannot poll fast enough.
Event FIFO and Request FIFO
The processor uses two FIFOs:
-
Event FIFO — outbound messages from the processor to the host. When a 1553 message triggers an event, the processor places the message data on this FIFO. The IDR mechanism then delivers it to the host over Ethernet.
-
Request FIFO — inbound commands from the host to the processor. When the host needs to update transmit data, it places the request on this FIFO. The processor handles the update safely, without conflicting with active 1553 transactions.
|
Important
|
While processor control is enabled, the host must not access the SUMMIT 1553 core memory directly. Doing so may change the value of the core’s "page" register, resulting in unpredictable behavior. Use the |
Ethernet IDR Configuration
Before configuring the RT itself, the application sets up the Ethernet IDR mechanism. This is handled by Setup_SUM1553_EthernetIDR(), which configures both the host-side socket and the board-side event routing.
IDR Socket Setup
/* Open connection to receive our interrupt driven replies (IDRs) */
check_status(nai_ether_Open(idrsock, bUDP, (const char*)brdipaddr, (const char*)szport, 500));
check_status(nai_ether_GetSockInfo(*idrsock,&type,ip,&port)); /* Retrieve callback information for IDR socket */
check_status(naibrd_DirectInterrupts(cardIndex,NAI_INTF_ETHER)); /* Send any interrupts we get over ethernet */
The host opens an Ethernet socket to the board using nai_ether_Open(). The protocol (UDP or TCP) is determined by the board connection type — UDP uses port 1044, TCP uses port 23. nai_ether_GetSockInfo() retrieves the socket’s callback address information, which is needed to configure the board’s IDR routing. naibrd_DirectInterrupts() tells the board to route all interrupts over Ethernet rather than through a local bus mechanism.
Event and UPR Configuration
/* Event Setup */
check_status(naibrd_SUM1553_Proc_RT_SetEventSAMask(cardIndex,module,rtchan,0,0xFFFFFFFF)); /* Trigger event 0 on any subaddress */
check_status(naibrd_SUM1553_Proc_SetEventVector(cardIndex,module,rtchan,0,EVENT0_VECTOR)); /* Generate interrupt vector 0x12 for event 0 */
/* Configure our IDR */
check_status(naibrd_SUM1553_Proc_SetEventUPR(cardIndex,module,rtchan,0,type | NAI_ETHER_UPR_TYPE_IDR,ip,port,EVENT0_SEQHI,EVENT0_VECTOR));
Three API calls configure the event-to-IDR pipeline:
-
naibrd_SUM1553_Proc_RT_SetEventSAMask()— configures Event 0 to trigger on messages received at any subaddress (mask0xFFFFFFFFmeans all 32 subaddresses). In your own application, you can mask specific subaddresses to filter which messages generate events. -
naibrd_SUM1553_Proc_SetEventVector()— assigns interrupt vector0x12(EVENT0_VECTOR) to Event 0. When the event fires, this vector is generated. -
naibrd_SUM1553_Proc_SetEventUPR()— configures the board to send an Unprompted Reply (UPR) over Ethernet when the EVENT0_VECTOR interrupt occurs. The UPR contains the Event FIFO data (the received 1553 message). TheEVENT0_SEQHIvalue (0x99) is embedded in the sequence number of the Ethernet message so the host can identify which event triggered the UPR.
|
Important
|
|
RT Configuration with Processor Control
The Setup_SUM1553_RT_ProcCtrl() function handles the full RT configuration sequence, including channel reset, mode selection, interrupt setup, subaddress legalization, and processor enablement.
Channel Reset and Mode Selection
/* Reset the channel */
check_status(naibrd_SUM1553_Reset(cardIndex,module,rtchan));
/* Wait for channels to reset */
while(check_status(naibrd_SUM1553_IsResetting(cardIndex,module,rtchan,&resetting)) == NAI_SUCCESS && resetting);
/* Configure RT */
check_status(naibrd_SUM1553_SetMode(cardIndex,module,rtchan,NAI_SUM1553_OPSTATUS_RT_MODE)); /* Configure as RT */
The channel is reset, polled until complete, and placed into RT mode — the same sequence used in the Ping-Pong sample.
Interrupt Configuration
check_status(naibrd_SUM1553_SetInterruptMask(cardIndex,module,rtchan,NAI_SUM1553_INTERRUPT_SUBA)); /* Enable SUBA interrupts */
The subaddress access (SUBA) interrupt must be enabled for processor control to work. When a 1553 message is received on a subaddress, this interrupt fires, which in turn triggers the processor to read the message and place it on the Event FIFO. Without this interrupt enabled, the processor has no way to know when new messages arrive.
Bus, Address, and Ping-Pong Configuration
check_status(naibrd_SUM1553_RT_SetBusEnable(cardIndex,module,rtchan,1,1)); /* Enable bus A and bus B */
check_status(naibrd_SUM1553_RT_SetAddress(cardIndex,module,rtchan,rtaddr)); /* Set RT address */
check_status(naibrd_SUM1553_RT_ConfigureForPingPong(cardIndex,module,rtchan)); /* Set up descriptor table with ping pong buffers */
check_status(naibrd_SUM1553_RT_SetPingPongEnable(cardIndex,module,rtchan,1)); /* Enable ping pong */
Even with processor control enabled, ping-pong buffering is still used at the hardware level. The processor manages the buffer alternation internally — you do not need to perform the manual disable/write/re-enable protocol that the Ping-Pong sample requires for host-side updates.
Per-Subaddress Interrupt Masks
for (sa = 1; sa <= 30; sa++)
check_status(naibrd_SUM1553_RT_SetSAMCInterruptMask(cardIndex,module,rtchan,NAI_SUM1553_SAMCTYPE_RX,sa,NAI_SUM1553_SA_IRQ_ACCESS));
In addition to the global SUBA interrupt, each subaddress must have its own access interrupt enabled. This loop enables receive-direction access interrupts for subaddresses 1 through 30. Subaddresses 0 and 31 are excluded because they are reserved for mode codes in MIL-STD-1553. The NAI_SUM1553_SA_IRQ_ACCESS flag triggers the interrupt when the subaddress data block is accessed (i.e., when a new message is written).
Subaddress Legalization and Interrupt Vector
check_status(naibrd_SUM1553_RT_Legalize(cardIndex,module,rtchan,NAI_SUM1553_SAMCTYPE_RX,0xFFFFFFFF,1)); /* Legalize for rx */
check_status(naibrd_SUM1553_RT_Legalize(cardIndex,module,rtchan,NAI_SUM1553_SAMCTYPE_TX,0xFFFFFFFF,1)); /* Legalize for tx */
check_status(naibrd_SUM1553_SetInterruptVector(cardIndex,module,rtchan,INTERRUPT_VECTOR));
All subaddresses are legalized for both receive and transmit directions (mask 0xFFFFFFFF). The channel-level interrupt vector is set to 0x10 (INTERRUPT_VECTOR). This vector must not overlap with the event vector (0x12) used for IDR routing.
Enabling Processor Control
/* Enable processor control */
check_status(naibrd_SUM1553_Proc_ClearFifo(cardIndex,module,rtchan,NAI_SUM1553_PROC_FIFO_ALL));
check_status(naibrd_SUM1553_Proc_SetCtrl(cardIndex,module,rtchan,NAI_SUM1553_PROC_CTRL_ENABLE));
Before enabling the processor, all FIFOs are cleared to remove any stale data from previous runs. naibrd_SUM1553_Proc_SetCtrl() with NAI_SUM1553_PROC_CTRL_ENABLE activates the on-module processor. From this point forward, the processor handles all message buffering and event generation.
Loading Initial Transmit Data and Starting Execution
/* Load the subaddress transmit data */
Update_SUM1553_ProcRTSAXmitData(cardIndex,module,rtchan,0);
/* Run the RT */
check_status(naibrd_SUM1553_EnableExecution(cardIndex,module,rtchan,1));
Initial transmit data for subaddress 3 is loaded via the processor’s Request FIFO (using naibrd_SUM1553_Proc_RT_LoadDataBlock() internally). Then RT execution is started.
|
Important
|
|
Receiving Messages via IDR
The Retrieve_SUM1553_ProcBCRTMessages() function listens on the IDR socket for a specified duration and displays any received 1553 messages. This is the primary data retrieval mechanism in this sample — no polling of the module’s memory is performed.
static void Retrieve_SUM1553_ProcBCRTMessages(int32_t cardIndex, int32_t module, int32_t rtchan, nai_socket_t idrsock, int32_t duration)
{
time_t end;
uint8_t idrmsg[NAI_ETHER_MAX_MESSAGE];
uint16_t seq;
nai_ether_gen_t gen = NAI_ETHER_GEN3;
nai_ether_typecode_t tc;
int32_t size, offset;
uint16_t rxdatablock[32], rxwordcnt;
int32_t i;
bool_t bNewMsg;
end = time(NULL) + duration;
while (time(NULL) < end)
{
/* Receive a message from the IDR socket */
offset = nai_ether_ReceiveMessage(idrsock,idrmsg,sizeof(idrmsg),&seq,&tc,gen,&size,5000);
if (offset < 0) /* Timed out */
continue;
if ((seq >> 8) == EVENT0_SEQHI) /* Received our event 0 message */
{
uint16_t timestamp;
uint16_t rxsa,info;
nai_sum1553_samctype_t samctype;
nai_sum1553_eventtype_t event;
if (naibrd_SUM1553_Proc_ProcessEventUPR(cardIndex,module,rtchan,idrmsg,tc,gen,offset,&event,&samctype,&rxsa,&rxwordcnt,&info,×tamp,NULL,NULL,rxdatablock) >= 0)
{
switch (event)
{
case NAI_SUM1553_EVENT_TYPE_SA:
/* Only display if data changed from previous read */
if (rxwordcnt == 0)
rxwordcnt = 32;
bNewMsg = FALSE;
for (i = 0; i < rxwordcnt; i++)
{
if (rxdatablock[i] != datablock[rxsa][i])
{
bNewMsg = TRUE;
break;
}
}
if (bNewMsg)
{
for (i = 0; i < rxwordcnt; i++)
datablock[rxsa][i] = rxdatablock[i];
printf("SA %d: ",rxsa);
printf("TimeTag: %04X ", timestamp);
printf("Data: ");
for (i = 0; i < rxwordcnt; ++i)
{
if (i != 0)
printf(",");
printf("%04X", rxdatablock[i]);
}
printf("\n");
}
break;
case NAI_SUM1553_EVENT_TYPE_ERROR:
printf("Received error event: %04x\n",info);
break;
}
}
}
else
{
printf("Received unknown message with seq %04x\n",seq);
}
}
}
The retrieval loop operates as follows:
-
Receive an Ethernet message —
nai_ether_ReceiveMessage()blocks for up to 5000 ms waiting for an incoming message on the IDR socket. If no message arrives within the timeout, it returns a negative offset and the loop continues. -
Identify the message source — the upper byte of the sequence number is compared against
EVENT0_SEQHI(0x99). If it matches, this is an Event 0 UPR from our configured IDR. Messages with other sequence numbers are logged as unknown. -
Decode the UPR —
naibrd_SUM1553_Proc_ProcessEventUPR()parses the raw Ethernet message and extracts the event type, subaddress, word count, timestamp, and data words. This function handles the protocol decoding so your application receives clean, structured data. -
Filter duplicate data — the sample compares received data against the previous values stored in
datablock[][]. Only messages with changed data are displayed. This avoids flooding the console when the BC is sending the same data repeatedly. -
Handle error events — if the event type is
NAI_SUM1553_EVENT_TYPE_ERROR, the error info code is displayed. Refer to the SUMMIT 1553 module manual for error code definitions.
|
Important
|
|
Updating RT Transmit Data via Request FIFO
The Update_SUM1553_ProcRTSAXmitData() function updates the data the RT sends in response to RT-to-BC requests on subaddress 3. With processor control active, the host must not write to the SUMMIT 1553 core memory directly. Instead, the update is submitted through the processor’s Request FIFO.
static void Update_SUM1553_ProcRTSAXmitData(int32_t cardIndex, int32_t module, int32_t rtchan, uint8_t increment)
{
uint16_t sa = DEF_RT_SUBADDR;
uint16_t txdatablock[32];
uint8_t msb, lsb;
int32_t i;
msb = (uint8_t)(sa << 4) + (increment & 0x0F);
lsb = 0;
for (i = 0; i < 32; i++)
{
txdatablock[i] = (msb << 8) | (uint8_t)(lsb + i);
}
/* Update the data */
check_status(naibrd_SUM1553_Proc_RT_LoadDataBlock(cardIndex, module, rtchan, NAI_SUM1553_SAMCTYPE_SA | NAI_SUM1553_SAMCTYPE_TX, sa, txdatablock, 0, 32));
}
naibrd_SUM1553_Proc_RT_LoadDataBlock() places the data update on the Request FIFO. The processor picks up the request and safely writes the data to the appropriate subaddress buffer without conflicting with active 1553 transactions. The parameters specify:
-
NAI_SUM1553_SAMCTYPE_SA | NAI_SUM1553_SAMCTYPE_TX— target the transmit direction of a subaddress descriptor. -
sa— the subaddress number (3 in this sample). -
txdatablock— the 32-word data payload. -
0, 32— starting word offset 0, word count 32 (full block).
Contrast with Ping-Pong Transmit Updates
In the Ping-Pong sample, updating transmit data requires a manual disable/write/re-enable protocol to avoid conflicting with the core’s buffer access. With processor control, this complexity is eliminated — naibrd_SUM1553_Proc_RT_LoadDataBlock() handles the buffer synchronization internally through the Request FIFO.
Request FIFO Priority
If NAI_SUM1553_PROC_CTRL_HPRIOREQ is enabled (it is not in this sample), requests on the Request FIFO take priority over 1553 message interrupt processing. This can be useful when you need guaranteed latency for transmit data updates, but it may delay event processing. Consult the SUMMIT 1553 module manual for details on priority configuration.
|
Important
|
|
Troubleshooting Reference
This table summarizes common errors and symptoms covered in the sections above. For detailed context on each entry, refer to the relevant section. Consult your module’s manual for hardware-specific diagnostic procedures.
| Error / Symptom | Possible Causes | Suggested Resolution |
|---|---|---|
No board found or connection timeout |
Board not powered, missing configuration file, network issue |
Verify hardware and configuration. If file doesn’t exist, configure and save from board menu. |
Module not recognized as SUMMIT 1553 |
Selected module is not N7/N8/NA/NB/NC. |
Verify module type at the selected slot. |
Reset not completing |
Hardware not responding after reset |
Verify module is powered and seated properly. |
IDR socket open failure |
Board IP unreachable, port blocked by firewall |
Verify network connectivity and that port 1044 (UDP) or 23 (TCP) is not blocked. |
No IDR messages received |
Interrupts not routed to Ethernet, event mask is zero, SUBA interrupt not enabled |
Verify |
RT not responding to BC commands |
Wrong RT address, subaddresses not legalized, bus not enabled |
Verify RT address matches BC target, subaddresses are legalized, and Bus A/B are enabled. |
Processor not generating events |
Per-subaddress interrupt masks not set |
Ensure |
"Received unknown message" in output |
Sequence number mismatch, other source on same socket |
Verify EVENT0_SEQHI and EVENT0_VECTOR match the IDR configuration. |
Error events reported |
Hardware-level 1553 bus error |
Check the |
Transmit data update not taking effect |
Request FIFO full or processor not enabled |
Verify processor control is enabled and check the return status of |
Unpredictable behavior |
Host accessed core memory directly while processor control was active |
Reset channel and reconfigure. Use only |
Interrupt vector collision |
EVENT0_VECTOR and INTERRUPT_VECTOR set to the same value |
Ensure the two vectors are different (sample uses 0x12 and 0x10 respectively). |
Full Source
The complete source for this sample is provided below for reference. The sections above explain each part in detail.
Full Source — SUM1553_RT_ProcCtrl.c (SSK 1.x)
#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"
/* Common 1553 Sample Program include files */
#include "nai_1553_utils.h"
/* naibrd include files */
#include "nai.h"
#include "naibrd.h"
#include "functions/naibrd_sum1553.h"
#include "advanced/nai_ether_adv.h"
/* Extern Functions or Variables*/
extern NAIAPPFUNC naiapp_syscfg_access_t g_NAISysCfgAccess[NAI_MAX_CARDS];
static const int8_t *CONFIG_FILE = (int8_t *)"default_SUM1553_RTProc.txt";
/* Function prototypes */
static bool_t Run_SUM1553_RT_ProcCtrl(int32_t cardIndex, int32_t module, uint32_t modid);
static void Setup_SUM1553_EthernetIDR(int32_t cardIndex, int32_t module, int32_t rtchan, int8_t *brdipaddr, bool_t bUDP, int8_t *szport, nai_socket_t *idrsock);
static void Setup_SUM1553_RT_ProcCtrl(int32_t cardIndex, int32_t module, int32_t rtchan, uint8_t rtaddr);
static void Retrieve_SUM1553_ProcBCRTMessages(int32_t cardIndex, int32_t module, int32_t rtchan, nai_socket_t idrsock, int32_t duration);
static void Update_SUM1553_ProcRTSAXmitData(int32_t cardIndex, int32_t module, int32_t rtchan, uint8_t increment);
int32_t GetBoardIndex(int32_t CardIndex);
static const int32_t DEF_RT_CHANNEL = 1;
static const uint8_t DEF_RT_ADDRESS = 1;
static const uint8_t DEF_RT_SUBADDR = 3;
static const uint8_t EVENT0_SEQHI = 0x99;
static uint16_t datablock[32][32];
/**************************************************************************************************************/
/**
<summary>
The purpose of the SUM1553_RT_ProcCtrl is to illustrate the methods to call in the naibrd library to configure
the 1553 channel as a Remote Terminal with the 1553 Processor Enabled to handle retrieving BC-RT messages and
placing these messages on the "Event" FIFO. This application will configure an IDR (Interrupt Driven Reply)
Ethernet message so that messages placed on the "Event" FIFO by the 1553 Processor are automatically sent to the
host as Unprompted Relies (UPRs) when the 1553 Processor generates an interrupt after placing a 1553 message
on the "Event" FIFO.
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
Note, the SUM1553_RT_ProcCtrl can run in conjunction with the SUM1553_BC_Scheduler applications to illustrate
BC and RT operations together with the NAI 1553 module.
</summary>
*/
/**************************************************************************************************************/
#if defined (__VXWORKS__)
int32_t SUM1553_RT_ProcCtrl(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_SUM1553_RT_ProcCtrl(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;
}
/**************************************************************************************************************/
/**
<summary>
Run_SUM1553_RT_ProcCtrl queries the user for the module and channel to configure as the Remote Terminal (RT).
After getting the module/channel selection, Setup_SUM1553_EthernetIDR() is invoked to configure the host to
handle Ethernet messages in response to the Interrupt from the 1553 Processor. Setup_SUM1553_RT_ProcCtrl() is
invoked to configure the 1553 channel for 1553 Processor RT control.
Once the Processor Controlled RT is configured and running, the user can:
1) Type 'U' to place a message on the "Request" FIFO to change the data for the RT-BC message.
2) Type a numeric duration (in seconds) value to view the BC-RT messages that are received from all subaddresses.
3) Type 'Q' to quit stop the RT execution and exit the routine.
</summary>
*/
/**************************************************************************************************************/
static bool_t Run_SUM1553_RT_ProcCtrl(int32_t cardIndex, int32_t module, uint32_t modid)
{
bool_t bQuit = FALSE;
bool_t bContinue = TRUE;
int32_t rtchan = 1;
uint8_t rtaddr = 1;
int32_t brdIndex = -1;
bool_t bUDP;
int8_t szPort[NAI_MAX_PORT_LEN];
nai_socket_t idrsock = (nai_socket_t)-1;
int32_t duration = 5;
uint8_t increment = 0;
int8_t inputBuffer[80];
int32_t inputResponseCnt;
bQuit = Get1553RTCfg(modid, DEF_RT_CHANNEL, DEF_RT_ADDRESS, &rtchan, &rtaddr);
if (!bQuit)
{
brdIndex = GetBoardIndex(cardIndex);
if (brdIndex != -1)
{
if (strlen((const char*)g_NAISysCfgAccess[brdIndex].etherCfg.ipAddress) > 0)
{
if (g_NAISysCfgAccess[brdIndex].comm == NAIBRD_COMM_ETHER_UDP)
{
bUDP = TRUE;
strcpy((char *)szPort, "1044");
}
else
{
bUDP = FALSE;
strcpy((char *)szPort, "23");
}
Setup_SUM1553_EthernetIDR(cardIndex, module, rtchan, g_NAISysCfgAccess[brdIndex].etherCfg.ipAddress, bUDP, &szPort[0], &idrsock);
}
Setup_SUM1553_RT_ProcCtrl(cardIndex, module, rtchan, rtaddr);
while (bContinue)
{
printf("\nType U to update the subaddress transmit data or duration for RT test or %c to quit (default: 5) : ", NAI_QUIT_CHAR);
bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
if (!bQuit)
{
if (toupper(inputBuffer[0]) == 'U')
{
increment++;
Update_SUM1553_ProcRTSAXmitData(cardIndex,module,rtchan,increment);
}
else
{
if (inputResponseCnt == 0)
duration = 5;
else
duration = (int32_t)atol((const char*)inputBuffer);
Retrieve_SUM1553_ProcBCRTMessages(cardIndex, module, rtchan, idrsock, duration);
}
}
else
bContinue = FALSE;
}
/* Disable the RT */
check_status(naibrd_SUM1553_EnableExecution(cardIndex,module,rtchan,0));
}
}
return bQuit;
}
/**************************************************************************************************************/
/**
<summary>
Setup_SUM1553_EthernetIDR() is invoked to configure the host to handle Ethernet messages in response to the
Interrupt from the 1553 Processor as well as setting up the board to generate the an Ethernet message when the
Interrupt occurs.
</summary>
*/
/**************************************************************************************************************/
static void Setup_SUM1553_EthernetIDR(int32_t cardIndex, int32_t module, int32_t rtchan, int8_t *brdipaddr, bool_t bUDP, int8_t *szport, nai_socket_t *idrsock)
{
nai_ether_upr_type_t type;
uint8_t ip[NAI_MAX_IP_LEN];
uint16_t port;
const uint16_t EVENT0_VECTOR = 0x12;
/* Open connection to receive our interrupt driven replies (IDRs) */
check_status(nai_ether_Open(idrsock, bUDP, (const char*)brdipaddr, (const char*)szport, 500));
check_status(nai_ether_GetSockInfo(*idrsock,&type,ip,&port)); /* Retrieve callback information for IDR socket */
check_status(naibrd_DirectInterrupts(cardIndex,NAI_INTF_ETHER)); /* Send any interrupts we get over ethernet */
/* Event Setup */
check_status(naibrd_SUM1553_Proc_RT_SetEventSAMask(cardIndex,module,rtchan,0,0xFFFFFFFF)); /* Trigger event 0 when we receive a message on any subaddress */
check_status(naibrd_SUM1553_Proc_SetEventVector(cardIndex,module,rtchan,0,EVENT0_VECTOR)); /* Generate interrupt vector EVENT0_VECTOR when event 0 is triggered */
/* Configure our IDR */
check_status(naibrd_SUM1553_Proc_SetEventUPR(cardIndex,module,rtchan,0,type | NAI_ETHER_UPR_TYPE_IDR,ip,port,EVENT0_SEQHI,EVENT0_VECTOR)); /* Read from the event buffer when EVENT0_VECTOR is generated and send the contents to the host */
}
/**************************************************************************************************************/
/**
<summary>
Setup_SUM1553_RT_ProcCtrl() configures the 1553 channel for 1553 Processor RT control.
</summary>
*/
/**************************************************************************************************************/
static void Setup_SUM1553_RT_ProcCtrl(int32_t cardIndex, int32_t module, int32_t rtchan, uint8_t rtaddr)
{
bool_t resetting;
uint16_t sa;
const uint16_t INTERRUPT_VECTOR = 0x10; /* Make sure this doesn't overlap with EVENT0_VECTOR */
/* Reset the channel */
check_status(naibrd_SUM1553_Reset(cardIndex,module,rtchan));
/* Wait for channels to reset */
while(check_status(naibrd_SUM1553_IsResetting(cardIndex,module,rtchan,&resetting)) == NAI_SUCCESS && resetting);
/* Configure RT */
check_status(naibrd_SUM1553_SetMode(cardIndex,module,rtchan,NAI_SUM1553_OPSTATUS_RT_MODE)); /* Configure as RT */
check_status(naibrd_SUM1553_SetInterruptMask(cardIndex,module,rtchan,NAI_SUM1553_INTERRUPT_SUBA)); /* Enable SUBA interrupts. This is necessary to trigger events when a message is received. */
check_status(naibrd_SUM1553_RT_SetBusEnable(cardIndex,module,rtchan,1,1)); /* Enable bus A and bus B */
check_status(naibrd_SUM1553_RT_SetAddress(cardIndex,module,rtchan,rtaddr)); /* Set RT address */
check_status(naibrd_SUM1553_RT_ConfigureForPingPong(cardIndex,module,rtchan)); /* Set up descriptor table with ping pong buffers */
check_status(naibrd_SUM1553_RT_SetPingPongEnable(cardIndex,module,rtchan,1)); /* Enable ping pong */
for (sa = 1; sa <= 30; sa++)
check_status(naibrd_SUM1553_RT_SetSAMCInterruptMask(cardIndex,module,rtchan,NAI_SUM1553_SAMCTYPE_RX,sa,NAI_SUM1553_SA_IRQ_ACCESS)); /* Enable Rx interrupts for subaddress */
check_status(naibrd_SUM1553_RT_Legalize(cardIndex,module,rtchan,NAI_SUM1553_SAMCTYPE_RX,0xFFFFFFFF,1)); /* Legalize the subaddresses we want for rx */
check_status(naibrd_SUM1553_RT_Legalize(cardIndex,module,rtchan,NAI_SUM1553_SAMCTYPE_TX,0xFFFFFFFF,1)); /* Legalize the subaddresses we want for tx*/
check_status(naibrd_SUM1553_SetInterruptVector(cardIndex,module,rtchan,INTERRUPT_VECTOR));
/* Enable processor control */
check_status(naibrd_SUM1553_Proc_ClearFifo(cardIndex,module,rtchan,NAI_SUM1553_PROC_FIFO_ALL));
check_status(naibrd_SUM1553_Proc_SetCtrl(cardIndex,module,rtchan,NAI_SUM1553_PROC_CTRL_ENABLE));
/* Load the subaddress transmit data */
Update_SUM1553_ProcRTSAXmitData(cardIndex,module,rtchan,0);
/* Run the RT */
check_status(naibrd_SUM1553_EnableExecution(cardIndex,module,rtchan,1));
}
/**************************************************************************************************************/
/**
<summary>
Retrieve_SUM1553_ProcBCRTMessages waits from a message from the Interrupt Driven Reply socket. Note to avoid
the constant output of messages, this routine will compare the data previous read from the current one received
and only display the message if the data has changed.
This routine will run for the period as specified by the duration in seconds passed in.
</summary>
*/
/**************************************************************************************************************/
static void Retrieve_SUM1553_ProcBCRTMessages(int32_t cardIndex, int32_t module, int32_t rtchan, nai_socket_t idrsock, int32_t duration)
{
time_t end;
uint8_t idrmsg[NAI_ETHER_MAX_MESSAGE];
uint16_t seq;
nai_ether_gen_t gen = NAI_ETHER_GEN3;
nai_ether_typecode_t tc;
int32_t size, offset;
uint16_t rxdatablock[32], rxwordcnt;
int32_t i;
bool_t bNewMsg;
end = time(NULL) + duration;
while (time(NULL) < end)
{
/* Receive a message from the IDR socket */
offset = nai_ether_ReceiveMessage(idrsock,idrmsg,sizeof(idrmsg),&seq,&tc,gen,&size,5000);
if (offset < 0) /* Timed out */
continue;
if ((seq >> 8) == EVENT0_SEQHI) /* Received our event 0 message */
{
uint16_t timestamp;
uint16_t rxsa,info;
nai_sum1553_samctype_t samctype;
nai_sum1553_eventtype_t event;
if (naibrd_SUM1553_Proc_ProcessEventUPR(cardIndex,module,rtchan,idrmsg,tc,gen,offset,&event,&samctype,&rxsa,&rxwordcnt,&info,×tamp,NULL,NULL,rxdatablock) >= 0) /* Decode IDR */
{
switch (event) /* What happened? */
{
case NAI_SUM1553_EVENT_TYPE_SA:
/* Only display if data from the subaddress is different from previous data received */
if (rxwordcnt == 0)
rxwordcnt = 32;
bNewMsg = FALSE;
for (i = 0; i < rxwordcnt; i++)
{
if (rxdatablock[i] != datablock[rxsa][i])
{
bNewMsg = TRUE;
break;
}
}
if (bNewMsg)
{
for (i = 0; i < rxwordcnt; i++)
datablock[rxsa][i] = rxdatablock[i];
printf("SA %d: ",rxsa);
printf("TimeTag: %04X ", timestamp);
printf("Data: ");
for (i = 0; i < rxwordcnt; ++i)
{
if (i != 0)
printf(",");
printf("%04X", rxdatablock[i]);
}
printf("\n");
}
break;
case NAI_SUM1553_EVENT_TYPE_ERROR:
printf("Received error event: %04x\n",info);
break;
}
}
}
else
{
printf("Received unknown message with seq %04x\n",seq);
}
}
}
/**************************************************************************************************************/
/**
<summary>
Update_SUM1553_ProcRTSAXmitData changes the data that is sent in response to the RT-BC messages sent to the
"DEF_RT_SUBADDR" Subaddress. The naibrd_SUM1553_Proc_RT_LoadDataBlock() is called to place the updated data on
the "Request" FIFO. Note, while in Processor controlled mode, the host should not access the Core memory directly.
Doing so may result in changing the value of the "page" register resulting in unpredictable behavior.
If the NAI_SUM1553_PROC_CTRL_HPRIOREQ is enabled (1), the requests will have higher priority
than the 1553 message interrupts.
</summary>
*/
/**************************************************************************************************************/
static void Update_SUM1553_ProcRTSAXmitData(int32_t cardIndex, int32_t module, int32_t rtchan, uint8_t increment)
{
uint16_t sa = DEF_RT_SUBADDR;
uint16_t txdatablock[32];
uint8_t msb, lsb;
int32_t i;
msb = (uint8_t)(sa << 4) + (increment & 0x0F); /* upper byte (subaddress=upper 4 bits | increment=lower 4 bits)) */
lsb = 0;
for (i = 0; i < 32; i++)
{
txdatablock[i] = (msb << 8) | (uint8_t)(lsb + i); /* incremental data */
}
/* Update the data */
check_status(naibrd_SUM1553_Proc_RT_LoadDataBlock(cardIndex, module, rtchan, NAI_SUM1553_SAMCTYPE_SA | NAI_SUM1553_SAMCTYPE_TX, sa, txdatablock, 0, 32));
}
int32_t GetBoardIndex(int32_t CardIndex)
{
int32_t brdIndex = -1;
int32_t i;
for (i = 0; i < naiapp_GetBoardCnt(); i++)
{
if (g_NAISysCfgAccess[i].cardIndex == CardIndex)
{
brdIndex = i;
break;
}
}
return brdIndex;
}