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

SD Interrupts

SD Interrupts

Explanation

About the Sample Application Code for NAI Embedded Function Modules

This application demonstrates how to configure and handle Synchro/Resolver (SD) interrupts using North Atlantic Industries (NAI) embedded function modules. It includes necessary setup routines, user interaction for selecting the module and channel, and also provides mechanisms to handle interrupt events either through polling or an Interrupt Service Routine (ISR).

Definitions

  • SD: Synchro/Resolver, typically used in reference to modules dealing with rotational measurements.

  • Interrupts: Hardware signals indicating that an event needs immediate attention from the software.

  • ISR: Interrupt Service Routine, a function invoked in response to an interrupt.

  • Card Index: Identifier for the board or card in use.

  • Module ID: Identifier for the module on the board.

  • Channel: Specific input/output path within a module.

Key Components

Include Files

Includes both standard C headers and specific headers for accessing NAI hardware functionalities:

  • Standard: stdio.h, stdlib.h, string.h, time.h, ctype.h

  • Application-specific: naiapp_boardaccess_menu.h, naiapp_boardaccess_query.h, naiapp_boardaccess_access.h, naiapp_boardaccess_display.h, naiapp_boardaccess_utils.h

  • NAI Specific: nai.h, naibrd.h, naibrd_sd.h, nai_ether_adv.h

Constants

  • CONFIG_FILE: Filename for the configuration settings.

  • SIGNAL_LOSS_THRESHOLD: Voltage threshold for detecting signal loss (70% of 90V).

  • MAX_ATTEMPT: Maximum retry attempts for signal status checking.

  • BAD_STATUS: A constant indicating a bad status signal.

  • DEF_SD_CHANNEL: Default channel used for the SD interrupt test.

  • SD_SIG_LOSS_INTERRUPT_VECTOR: Interrupt vector for SD signal loss.

Function Prototypes

  • Run_SD_Interrupts: Handles querying user for card/module/channel and configures SD interrupts.

  • Cfg_SD_Interrupt_Channel: Queries user for channel and handles SD interrupt configuration.

  • Setup_SD_Interrupt: Configures hardware settings for SD interrupts.

  • MySDIsr: ISR for handling SD interrupts.

  • checkForStatusChange: Checks for status change in a polling method.

Main Function Execution

The main function: 1. Initializes necessary variables and user input buffers. 2. Runs the board menu to configure settings using naiapp_RunBoardMenu. 3. Enters a loop to repeatedly query user for card and module indices, and then: - Gets the module ID. - If valid, retrieves the channel count and runs Run_SD_Interrupts. 4. Prompts user whether to quit or restart. 5. Closes all open cards before exiting.

Core Functionalities

Run_SD_Interrupts

Prompts user for inputs and validates the selected module for SD functionality. If valid, it proceeds to configure SD interrupts.

Cfg_SD_Interrupt_Channel

Prompts user for channel selection while setting up the SD Interrupts for the selected card/module/channel configuration.

Setup_SD_Interrupt

Handles the detailed configuration steps: 1. Sets up the SD mode to SYN (synchronization). 2. Configures the signal loss threshold. 3. Sets interrupt vectors and enables interrupts. 4. Clears any existing signal loss status. 5. Enters a loop waiting for interrupts, either via ISR (if enabled) or polling.

Handling Interrupts

  • Using ISR: Configures the ISR for the card and module interrupt vector.

  • Using Polling: Regularly checks the status register for changes.

ISR Function

MySDIsr increments the interrupt counter and identifies the received vector, indicating signal loss or logging unknown vectors.

Polling Function

checkForStatusChange regularly reads the signal status and updates the interrupt counters and flags accordingly.

Miscellaneous

Contains additional print statements and prompts to guide users through the process of interacting with the application and troubleshooting.


This sample application code is a comprehensive example of how to configure and use SD interrupts on NAI embedded function modules, providing both configuration routines and interrupt handling mechanisms to ensure robust interaction with the hardware.

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

/* Common Sample Program include files */
#include "include/naiapp_boardaccess_menu.h"
#include "include/naiapp_boardaccess_query.h"
#include "include/naiapp_boardaccess_access.h"
#include "include/naiapp_boardaccess_display.h"
#include "include/naiapp_boardaccess_utils.h"

/* naibrd include files */
#include "nai.h"
#include "naibrd.h"
#include "functions/naibrd_sd.h"
#include "advanced/nai_ether_adv.h"

static const int8_t *CONFIG_FILE = (const int8_t *)"default_SD_Interrupts.txt";

/*static const double SIGNAL_LOSS_THREHOLD = 63.0;   70% of 90V*/
static const double SIGNAL_LOSS_THREHOLD = 8.0;  /* 70% of 90V*/

static const int32_t MAX_ATTEMPT = 10;
static const uint8_t  BAD_STATUS = 1u;

/* Function prototypes */
void Run_SD_Interrupts(int32_t cardIndex, int32_t module, uint32_t ModuleID, int32_t MaxChannel);
void Cfg_SD_Interrupt_Channel(int32_t cardIndex, int32_t module, uint32_t ModuleID, int32_t MaxChannel);
void Setup_SD_Interrupt(int32_t cardIndex, int32_t module, uint32_t channel, uint32_t ModuleID);
#if !defined (RUN_ISR)
static void checkForStatusChange(int cardIndex, int module);
#endif

#if defined (__VXWORKS__)
void MySDIsr(uint32_t nVector);
#else
void MySDIsr(void* param, uint32_t vector);
#endif
uint32_t irqSDCount = 0;
static uint32_t receivedVector = 0;
static bool_t bReceivedInterrupt = FALSE;

static const int32_t DEF_SD_CHANNEL = 1;

#define SD_SIG_LOSS_INTERRUPT_VECTOR        0x30

//#define RUN_ISR						/* Un-Comment to use ISR, else Poll */

/**************************************************************************************************************/
/**
<summary>
The purpose of the SD_Interrupts is to illustrate the methods to call in the naibrd library to perform configuration
and handle SD Interrupts.

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 SD routines.
 - ClearDeviceCfg
 - QuerySystemCfg
 - DisplayDeviceCfg
 - GetBoardSNModCfg
 - SaveDeviceCfg
</summary>
*/
/**************************************************************************************************************/
#if defined (__VXWORKS__)
int32_t SD_Interrupts(void)
#else
int32_t main(void)
#endif
{
   bool_t stop = FALSE;
   int32_t cardIndex;
   int32_t moduleCnt;
   int32_t module;
   uint32_t moduleID = 0;
   int32_t numChannels;
   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))
               {
                  numChannels = naibrd_SD_GetChannelCount(moduleID);
                  Run_SD_Interrupts(cardIndex, module, moduleID, numChannels);
               }
            }
         }

         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_SD_Interrupts prompts the user for the card, module and channel to use for the application and calls
Cfg_SD_Interrupt_Channel if the card, module, channel is valid for as a discrete module.
</summary>
*/
/**************************************************************************************************************/
void Run_SD_Interrupts(int32_t cardIndex, int32_t module, uint32_t ModuleID, int32_t MaxChannel)
{
   if (MaxChannel == 0)
   {
      printf(" *** Module selection not recognized as SD module. ***\n\n");
   }
   else
   {
      Cfg_SD_Interrupt_Channel(cardIndex, module, ModuleID, MaxChannel);
   }
}

/**************************************************************************************************************/
/**
<summary>
Cfg_SD_Interrupt_Channel querying the user for the channel to generate and handle SD interrupts.
</summary>
*/
/**************************************************************************************************************/
void Cfg_SD_Interrupt_Channel(int32_t cardIndex, int32_t module, uint32_t ModuleID, int32_t MaxChannel)
{

   int32_t chan, defaultchan = 1;

   printf("\nSD Signal Loss Interrupt Test for high voltage 90VLL module:");
   printf("\nThe signal loss threshold voltage is set to 70%%(63V) of the input SD signal.");
   printf("\nEnsure a validated SD signal is applied to the device under test(DUT). ");
   printf("    \r\n\r\n");
   printf("Channel selection \r\n");
   printf("================= \r\n");
   defaultchan = DEF_SD_CHANNEL;
   naiapp_query_ChannelNumber(MaxChannel, defaultchan, &chan);

   Setup_SD_Interrupt(cardIndex, module, chan, ModuleID);
#if Debug
   printf("\nType %c to quit : ", NAI_QUIT_CHAR);
   bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
   if (!bQuit)
   {

   }
   else
      bContinue = FALSE;
#endif
}

void Setup_SD_Interrupt(int32_t cardIndex, int32_t module, uint32_t channel, uint32_t ModuleID)
{
   bool_t bContinue = TRUE;
   bool_t bQuit = FALSE;

   uint32_t SigLossStatus;
   int32_t retryCnt = 0;

   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

   printf("\nIn Setup_SD_Interrupt, card:%d, module:%d, channel:%d, mid:%x", cardIndex, module, channel, ModuleID);

   /*set up SD mode: SYN*/
   printf("\nSetup Syn mode");
   check_status(naibrd_SD_SetChanMode(cardIndex, module, channel, NAI_SD_SYNCHRO));
   /*set up SD signal loss threshold*/
   printf("\nSetup Signal Threshold");
   check_status(naibrd_SD_SetSigLossThreshold(cardIndex, module, channel, SIGNAL_LOSS_THREHOLD));
   /*set up SD signal loss interrupt vector*/
   printf("\nSetup Interrupt Vector");
   check_status(naibrd_SD_SetInterruptVector(cardIndex, module, NAI_SD_STATUS_SIGNAL_LATCHED, SD_SIG_LOSS_INTERRUPT_VECTOR));
   /* Set the Interrupt Type (Edge/Level) */
   printf("\nSetup Interrupt Edge/Level");
   check_status(naibrd_SD_SetEdgeLevelInterrupt(cardIndex, module, channel, NAI_SD_STATUS_SIGNAL_LATCHED, NAI_SD_EDGE_INTERRUPT));
   /* Set the Interrupt Steering */
   printf("\nSetup Interrupt Steering");
   naibrd_SD_SetInterruptSteering(cardIndex, module, NAI_SD_STATUS_SIGNAL_LATCHED, NAIBRD_INT_STEERING_ON_BOARD_0);
#if defined (RUN_ISR)
   /* Install the ISR */
   printf("\nSetup Interrupt ISR");
   naibrd_InstallISR(cardIndex, NAIBRD_IRQ_ID_ON_BOARD_0, (nai_isr_t)MySDIsr, NULL);
#endif
   /*clear any latch signal loss interrupt by writing to the signal loss status register */
   retryCnt = 0;
   do
   {
      printf("\nSetup Read Signal Loss Status");
      check_status(naibrd_SD_ClearStatus(cardIndex, module, channel, NAI_SD_STATUS_SIGNAL_LATCHED));
      naibrd_Wait(1000);
      check_status(naibrd_SD_GetStatus(cardIndex, module, channel, NAI_SD_STATUS_SIGNAL_LATCHED, &SigLossStatus));
   } while ((retryCnt < MAX_ATTEMPT) && (SigLossStatus == BAD_STATUS));

   printf("\nSetup Signal Loss Status cleared");
   if (SigLossStatus == BAD_STATUS)
   {
      printf("\nERROR: SD Signal Loss Status is set\n");
   }
   else
   {
      /* Enable BIT Interrupts */
      check_status(naibrd_SD_SetInterruptEnable(cardIndex, module, channel, NAI_SD_STATUS_SIGNAL_LATCHED, TRUE));

      printf("\n*** Waiting for Signal Loss Interrupt***\n");
      while (bContinue)
      {
#if !defined (RUN_ISR)
         checkForStatusChange(cardIndex, module);
#endif
         if (bReceivedInterrupt)
         {
            printf("SD Signal Loss Interrupt, Vector:0x%02X, SD irqCount:%d\n", receivedVector, irqSDCount);
            /*Show Status*/
            check_status(naibrd_SD_GetStatusRaw(cardIndex, module, NAI_SD_STATUS_SIGNAL_LATCHED, &SigLossStatus));
            printf("Signal Loss Status = 0x%0X\n", SigLossStatus);
            /*Clear Signal Loss*/
            check_status(naibrd_SD_ClearStatus(cardIndex, module, channel, NAI_SD_STATUS_SIGNAL_LATCHED));
            bReceivedInterrupt = FALSE;

            printf("\nType %c to quit. Enter to Continue.", NAI_QUIT_CHAR);
            bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
            printf("\n*** Waiting for Signal Loss Interrupt***\n");
            if (bQuit)
               bContinue = FALSE;
         }
      }
   }
}

#if defined (RUN_ISR)
/*****************************/
/* Interrupt Service Routine */
/*****************************/
#if defined (__VXWORKS__)
void MySDIsr(uint32_t nVector)
#else
void MySDIsr(void* param, uint32_t vector)
#endif
{
   irqSDCount++;

#if defined (__VXWORKS__)
   /* Get the vector that caused the interrupt */
   unsigned int vector = nai_Onboard_GetInterruptVector();
   /* Clear Interrupt */
   nai_Onboard_ClearInterrupt();
#endif

   /* Determine what interrupt was received */
   receivedVector = vector;
   switch (vector)
   {
      case SD_SIG_LOSS_INTERRUPT_VECTOR:
         bReceivedInterrupt = TRUE;
         break;
      default:
         printf("Unknown Interrupt, Vector:0x%02X, SD irqCount:%d\n", vector, irqSDCount);
         break;
   }
}
#else
static void checkForStatusChange(int cardIndex, int module)
{
   uint32_t SigLossStatus;
   check_status(naibrd_SD_GetStatusRaw(cardIndex, module, NAI_SD_STATUS_SIGNAL_LATCHED, &SigLossStatus));
   if (SigLossStatus != 0)
   {
      irqSDCount++;
      receivedVector = SD_SIG_LOSS_INTERRUPT_VECTOR;
      bReceivedInterrupt = TRUE;
   }
}
#endif

Help Bot

X