Integrator Resources

The official home for NAI Support

Not sure where to start? Try Quick Start Guide or ask a question below!

Toggle Components with Visual Button
JavaScript Form Processing

SUM1553 RT ProcCtrl

SUM1553 RT ProcCtrl

Explanation

About This Code

The provided C code is a sample application from North Atlantic Industries (NAI) designed to interact with NAI�s embedded function modules, specifically focusing on a MIL-STD-1553 interface. The application configures the 1553 channel as a Remote Terminal (RT) controlled by a 1553 processor. The process involves setting up multiple configurations and handling messages transmitted over an Ethernet-based Interrupt Driven Reply (IDR) mechanism.

Key Components:

  1. Header Files:

    • The core functionality is supported by NAI�s libraries, which are included using header files like 'nai.h', 'naibrd.h', 'naibrd_sum1553.h', etc.

    • Utility functions for 1553 bus interactions are included from 'nai_1553_utils.h'.

  2. Configuration Constants:

    • 'CONFIG_FILE': Specifies the configuration file to use.

    • 'DEF_RT_CHANNEL', 'DEF_RT_ADDRESS', 'DEF_RT_SUBADDR': Default values for RT channel, address, and subaddress.

  3. Function Prototypes:

    • Declare several static functions to handle various parts of the process, like setting up Ethernet IDRs, RT control, retrieving BC-RT (Bus Controller to Remote Terminal) messages, and updating RT subaddress transmit data.

Main Logic Flow:

  1. Main Function ('main'):

    • Starts the main loop by calling 'naiapp_RunBoardMenu' with the specified configuration file.

    • Enters a loop to query the user for card index and module number using 'naiapp_query_CardIndex' and 'naiapp_query_ModuleNumber'.

    • Calls 'Run_SUM1553_RT_ProcCtrl' to perform RT processing, and upon completion, asks the user whether to quit or restart.

  2. Run_SUM1553_RT_ProcCtrl:

    • Queries the user for the 1553 RT configuration using 'Get1553RTCfg'.

    • Sets up Ethernet IDR with 'Setup_SUM1553_EthernetIDR'.

    • Configures the RT processor control using 'Setup_SUM1553_RT_ProcCtrl'.

    • Enters a loop where the user can:

    • Type 'U' to update RT-BC message data.

    • Enter a duration to view received BC-RT messages.

    • Type 'Q' to quit.

  3. Setup Functions:

    • Setup_SUM1553_EthernetIDR: Configures the host to handle Ethernet messages in response to 1553 processor interrupts.

    • Setup_SUM1553_RT_ProcCtrl: Configures the 1553 channel as a processor-controlled RT.

  4. Message Handling Functions:

    • Retrieve_SUM1553_ProcBCRTMessages: Monitors the IDR socket for incoming messages, decodes them, and displays messages if data has changed.

    • Update_SUM1553_ProcRTSAXmitData: Updates the RT transmit data block for a specific subaddress.

  5. Helper Function:

    • GetBoardIndex: Retrieves the board index based on the card index.

Detailed Function Descriptions:

  1. 'Run_SUM1553_RT_ProcCtrl':

    • Queries for RT configuration.

    • Sets up Ethernet IDR and RT control.

    • Provides a user interface to interact with the RT setup.

  2. 'Setup_SUM1553_EthernetIDR':

    • Opens an Ethernet socket for IDR messages.

    • Configures interrupt management.

    • Sets up event handling and reply routing for Ethernet.

  3. 'Setup_SUM1553_RT_ProcCtrl':

    • Resets and configures the 1553 channel.

    • Sets RT mode and enables necessary interrupts.

    • Configures ping-pong buffer for RT.

    • Sets up address, legal subaddresses, and loads initial transmit data.

  4. 'Retrieve_SUM1553_ProcBCRTMessages':

    • Listens on the IDR socket for incoming messages.

    • Decodes and displays meaningful changes in messages.

  5. 'Update_SUM1553_ProcRTSAXmitData':

    • Updates the data block for a given subaddress in a processor-safe manner.

Conclusion:

This sample application demonstrates how to use the NAI�s libraries to configure and interact with a 1553 remote terminal setup. It offers a structured way to manage RT configurations, process messages, update data, and handle interrupts through Ethernet, making it easier to integrate and test 1553 functionalities in an embedded system.

#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"

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,&timestamp,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;
}

Help Bot

X