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

M1553 BC SendMessage WithRetries

M1553 BC SendMessage WithRetries

Explanation

About This C Application Code

The provided C sample application code is designed for North Atlantic Industries (NAI) hardware, specifically to configure the 1553 channel as a Bus Controller (BC) and send messages with retry mechanisms in case of failures. The code interacts with the NAI embedded function modules using the naibrd library. This document explains the code and its components.

Function Definitions and Enumerations

Constants

  • CONFIG_FILE: The default configuration file for 1553 Bus Controller (BC).

  • Message, Opcode, Frame, and Data Block Constants (MSG1, OP1, OP2, MNR1, MJR, DBLK1): Identifiers used for communication and operations on the 1553 bus.

  • Default Identifiers (DEF_M1553_CARD_INDEX, DEF_M1553_MODULE, DEF_M1553_CHANNEL, DEF_M1553_DEVNUM): Default values for the card index, module, channel, and device number.

  • RT_ADDRESS and RT_SUBADDRESS: Remote terminal address and subaddress values.

  • WORDCOUNT: Number of words in a data block.

Include Files

The application includes several standard and NAI-specific library header files:

  • Standard C Headers: stdio.h, stdlib.h, string.h, time.h

  • OS-Specific Headers: taskLib.h, applicable if compiled on VxWorks OS.

  • NAI Application Headers: Facilitate interaction with NAI boards (naiapp_boardaccess_menu.h, naiapp_boardaccess_query.h, naiapp_boardaccess_access.h, naiapp_boardaccess_display.h, naiapp_boardaccess_utils.h).

  • NAI 1553 Utility Headers: For 1553 communication utilities (nai_1553_utils.h, nai_1553_bc_utils.h).

  • NAI Board Headers: Essential for board interactions (nai.h, naibrd.h, naibrd_1553.h).

Key Functions

main or M1553_BC_SendMessage_WithRetries

The main function initializes the application, allowing user interaction to configure 1553 bus parameters and send messages. The main sequence is as follows:

  1. Initialization: Starts by running the board menu using naiapp_RunBoardMenu.

  2. User Queries: Continuously queries the user for configurations like the card index and module number.

  3. Message Sending: Calls Run_M1553_BC_SendMessage_WithRetries to send a message, incorporating a retry mechanism if required.

  4. Termination: Provides an option to quit and closes all open cards using naiapp_access_CloseAllOpenCards.

Run_M1553_BC_SendMessage_WithRetries

This function sets up the 1553 device as a bus controller (BC) and attempts to send a message, retrying in case of failure. It performs the following:

  1. Channel Query: Determines the supported channel based on the module ID.

  2. RunSendMessage: Calls the RunSendMessage function to carry out actual message sending operations.

RunSendMessage

Handles the process of sending a message with retries:

  1. Device Initialization: Opens and initializes the 1553 device.

  2. Retry Policy: Sets the retry policy for message sending.

  3. Data Block and Message Creation:

    • Creates BC data blocks and messages.

    • Configures commands and frame sequences for executing messages.

  4. Message Loop: Continuously sends messages, handles stopping and restarting BC, and outputs message details.

  5. Device Freeing: Frees the 1553 device before exiting.

Summary

The provided code sample demonstrates interactions with NAI embedded function modules to configure a 1553 bus controller, send messages, and handle retry logic in case of transmission failures. The structured use of functions and HAI utilities ensures efficient and organized communication setup and execution processes. The code can be run in different environments (e.g., VxWorks, Linux) by including conditional compilation directives.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

#if defined (__VXWORKS__)
 #include "taskLib.h"
#endif
/* 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"
#include "BC/nai_1553_bc_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_1553BC_SendMessage_WithRetries.txt";

/* Function prototypes */
static bool_t Run_M1553_BC_SendMessage_WithRetries(int32_t cardIndex, int32_t module, uint32_t modid);
static bool_t RunSendMessage(int32_t cardIndex, int32_t module, int32_t channel, uint32_t modid);

/* define message constants */
#define MSG1         1

/* define opcodes */
#define OP1          1
#define OP2          2

/* define frame constants */
#define MNR1         1
#define MJR          2

/* define data block numbers */
#define DBLK1        1

#define DEF_M1553_CARD_INDEX                 0
#define DEF_M1553_MODULE                     1
#define DEF_M1553_CHANNEL                    1
#define DEF_M1553_DEVNUM                     1

#define RT_ADDRESS                           1
#define RT_SUBADDRESS                        2

#define WORDCOUNT                            11

/**************************************************************************************************************/
/**
<summary>
The purpose of the M1553_BC_SendMessage_WithRetries is to illustrate the methods to call in the naibrd library\
to configure the 1553 channel as a Bus Controller and to send a 1553 message out. This code also sends a retry
message if the initial message fails to send or returns an error. The retry policy is set by the user.

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_BC_SendMessage_WithRetries(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_M1553_BC_SendMessage_WithRetries(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_M1553_BC_SendMessage_WithRetries initializes the 1553 device as a bus controller (BC) and sends out a message.
This routine demonstrates the following API functions in the 1553 naibrd library:
naibrd_1553_Open
naibrd_1553_Initialize
naibrd_1553_BcDataBlockCreate
naibrd_1553_BcMessageCreateBcToRt
naibrd_1553_BcCommandCreate
naibrd_1553_BcFrameCreate
naibrd_1553_BcDataBlockWrite
naibrd_1553_BcStart
naibrd_1553_BcStop
naibrd_1553_Free
</summary>
*/
/**************************************************************************************************************/
static bool_t Run_M1553_BC_SendMessage_WithRetries(int32_t cardIndex, int32_t module, uint32_t modid)
{
   bool_t bQuit = FALSE;
   int32_t channel;
   int32_t MaxChannel = 4;

   if (IsFTx1553(modid))
   {
      MaxChannel = 4;
      bQuit = naiapp_query_ChannelNumber(MaxChannel, DEF_M1553_CHANNEL, &channel);
      if (!bQuit)
      {
         bQuit = RunSendMessage(cardIndex, module, channel, modid);
      }
   }
   else if (IsFTx1760(modid))
   {
      MaxChannel = 2;
      bQuit = naiapp_query_ChannelNumber(MaxChannel, DEF_M1553_CHANNEL, &channel);
      if (!bQuit)
      {
         bQuit = RunSendMessage(cardIndex, module, channel, modid);
      }
   }
   else
      printf("\nThis module does not support 1553 functionality.\n");

   return bQuit;
}

static bool_t RunSendMessage(int32_t cardIndex, int32_t module, int32_t channel, uint32_t modid)
{
   int32_t i;
   bool_t bQuit = FALSE;
   uint32_t usBus;
   nai_1553_t status;
   uint16_t increment = 0;
   uint16_t aData[32] = {0};
   int16_t aOpCodes[20] = { 0 };
   bool_t bContinue = TRUE;
   int16_t devnum;
   bool_t bcToRtMsg = TRUE;
   naiDecodedMessageStructure DecodedMsgStruct;
   bool_t bSoftware;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

   /* Get the Logical Device Number */
   bQuit = Get1553LogicalDevNum(DEF_M1553_DEVNUM, &devnum);
   if (!bQuit)
   {
      /* Get Msg Direction */
      bQuit = GetMsgDirection(&bcToRtMsg);
      if (!bQuit)
      {
         /* Which bus are we firing on? */
         bQuit = GetBus(&usBus);
         if (!bQuit)
         {
            bQuit = Get1553BCSoftwareOverride(TRUE, &bSoftware);
            if (!bQuit)
            {
               /* Open 1553 Device(s) */
               status = naibrd_1553_Open(cardIndex, module, channel, devnum);
               if(status != 0)
               {
                  printf("Error: naibrd_1553_Open Ch %d, status = %d", channel, status);
                  return TRUE;
               }

               if (bSoftware)
               {
                  /* Override external BC_DISABLE and M1760 (In order to configure as BC, this needs to */
                  /* be set if BC_DISABLE and M1760 pins are not driven high) */
                  naibrd_1553_WriteAuxReg(devnum, 0x2, 0xA000);
               }
               else
               {
                  /* Do not override external BC_DISABLE and M1760 Inputs */
                  naibrd_1553_WriteAuxReg(devnum, 0x2, 0x0000);
               }

               if (modid == NAI_MODULE_ID_FT8)
               {
                  /* Simplex Enable (for NAI internal testing only, do not enable) */
                  /*naibrd_1553_WriteAuxReg(devnum, 0x3, 0x4000);
                    naibrd_1553_WriteAuxReg(devnum, 0xF, 0x0001);*/
               }

               /* Reset Device */
               naibrd_1553_WriteAuxReg(devnum, 0x1, 0x1);
#if defined (__VXWORKS__)
               taskDelay(1);
#elif defined (LINUX)
               usleep(100000);
#else
               Sleep(100);
#endif
               naibrd_1553_WriteAuxReg(devnum, 0x1, 0x0);

               /* Initialize 1553 Device(s) */
               status = naibrd_1553_Initialize(devnum, NAI_1553_ACCESS_CARD,NAI_1553_MODE_BC,0,0,0);
               if(status != 0)
               {
                  printf("Error: naibrd_1553_Initialize Ch %d, status = %d", channel, status);
                  return TRUE;
               }

               /* Set message retry policy
                  NOTE: The call below will setup the retry policy such that the first retry will go out on the same bus and the second retry will go out on the alternate bus.
                        The user may choose to retry on the same bus or alternate bus for both retries, or retry on the alternate bus first then back on the same bus.
                  */
               status = naibrd_1553_BcSetMessageRetryPolicy(devnum, NAI_1553_MESSAGE_RETRY_TWICE, NAI_1553_MESSAGE_RETRY_SAME, NAI_1553_MESSAGE_RETRY_ALT, 0);
               if(status != 0)
               {
                  printf("Error: naibrd_1553_BcSetMessageRetryPolicy Ch %d, status = %d", channel, status);
                  return TRUE;
               }

               /* Create BC Data Block */
               status = naibrd_1553_BcDataBlockCreate(devnum, DBLK1, WORDCOUNT, NULL, 0);
               if(status != 0)
               {
                  printf("Error: naibrd_1553_BcDataBlockCreate Ch %d, status = %d", channel, status);
                  return TRUE;
               }

               if (bcToRtMsg)
               {
                  /* Create BC to RT Message */
                  status = naibrd_1553_BcMessageCreateBcToRt(devnum, MSG1, DBLK1, RT_ADDRESS, RT_SUBADDRESS, WORDCOUNT, 0, usBus | NAI_1553_BC_CTRL_RETRY_ENABLED);
                  if (status != 0)
                  {
                     printf("Error: naibrd_1553_BcMessageCreateBcToRt status = %d", status);
                     return TRUE;
                  }
               }
               else
               {
                  /* Create RT to BC Message */
                  status = naibrd_1553_BcMessageCreateRtToBc(devnum, MSG1, DBLK1, RT_ADDRESS, RT_SUBADDRESS, WORDCOUNT, 0, usBus | NAI_1553_BC_CTRL_RETRY_ENABLED);
                  if (status != 0)
                  {
                     printf("Error: naibrd_1553_BcMessageCreateRtToBc status = %d", status);
                     return TRUE;
                  }
               }

               /* Create Execute Message Command */
               status = naibrd_1553_BcCommandCreate(devnum, OP1, NAI_1553_OPCODE_EXECUTE_MESSAGE, NAI_1553_OPCODE_COND_ALWAYS, MSG1, 0, 0);
               if (status != 0)
               {
                  printf("Error: naibrd_1553_BcCommandCreate status = %d", status);
                  return TRUE;
               }

               /* Create Call Subroutine Command */
               status = naibrd_1553_BcCommandCreate(devnum, OP2, NAI_1553_OPCODE_CALL_SUBROUTINE, NAI_1553_OPCODE_COND_ALWAYS, MNR1, 0, 0);
               if (status != 0)
               {
                  printf("Error: naibrd_1553_BcCommandCreate status = %d", status);
                  return TRUE;
               }

               /* Create Minor Frame */
               aOpCodes[0] = OP1;
               status = naibrd_1553_BcFrameCreate(devnum, MNR1, NAI_1553_BC_FRAME_MINOR, aOpCodes, 1, 0, 0);
               if (status != 0)
               {
                  printf("Error: naibrd_1553_BcFrameCreate status = %d", status);
                  return TRUE;
               }

               /* Create Major Frame */
               aOpCodes[0] = OP2;
               status = naibrd_1553_BcFrameCreate(devnum,MJR,NAI_1553_BC_FRAME_MAJOR,aOpCodes,1,1000,0);
               if (status != 0)
               {
                  printf("Error: naibrd_1553_BcFrameCreate status = %d", status);
                  return TRUE;
               }

               while (bContinue)
               {
                  /* Load BC data block with incremental data */
                  for (i = 0; i < WORDCOUNT; i++)
                  {
                     aData[i] = increment++;
                  }
                  status = naibrd_1553_BcDataBlockWrite(devnum, DBLK1, aData, WORDCOUNT, 0);
                  if (status != 0)
                  {
                     printf("Error: naibrd_1553_BcDataBlockWrite status = %d", status);
                     return TRUE;
                  }

                  /* Start BC */
                  status = naibrd_1553_BcStart(devnum,MJR,1);
                  if (status != 0)
                  {
                     printf("Error: naibrd_1553_BcStart status = %d", status);
                     return TRUE;
                  }

                  /* This delay is necessary to allow the BC to run */
                  nai_msDelay(200);

                  /* Stop BC */
                  status = naibrd_1553_BcStop(devnum);
                  if (status != 0)
                  {
                     printf("Error: naibrd_1553_BcStop status = %d", status);
                     return TRUE;
                  }

                  /* Get Decoded Msg Structure */
                  status = naibrd_1553_BcMessageGetByIdDecoded(devnum, MSG1, &DecodedMsgStruct, 1);
                  if (status < 0)
                  {
                     printf("Error: naibrd_1553_BcMessageGetByIdDecoded status = %d", status);
                     return TRUE;
                  }
                  else if (status > 0)
                  {
                     printf("Control Word: 0x%04X\n", DecodedMsgStruct.wBcControlWord);
                     printf("Command Word: 0x%04X\n", DecodedMsgStruct.wCommandWord1);
                     printf("Block Status: 0x%04X\n", DecodedMsgStruct.wBlockStatus);
                     printf("Time Tag: 0x%04X\n", DecodedMsgStruct.wTimeTag);
                     printf("Word Count: 0x%04X\n", DecodedMsgStruct.wDataWordCount);
                     printf("RT Status Word: 0x%04X\n", DecodedMsgStruct.wStatus1);
                     if (!bcToRtMsg)
                     {
                        printf("Data:");
                        for (i = 0; i < DecodedMsgStruct.wDataWordCount; i++)
                        {
                           if (i % 8 == 0)
                           {
                             printf("\n");
                           }
                           printf("0x%04X ", DecodedMsgStruct.waData[i]);
                        }
                     }
                     printf("\n\n");
                  }

                  printf("\nPress any key to send another message or Q to quit.");
                  bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
                  if (bQuit)
                  {
                     bContinue = FALSE;
                  }
               }
            }
         }
      }
   }

   /* Free 1553 Device */
   status = naibrd_1553_Free(devnum);
   if (status != 0)
   {
      printf("Error: naibrd_1553_Free status = %d", status);
      return TRUE;
   }

   return bQuit;
}

Help Bot

X