nai ttl int
Edit this on GitLab
nai ttl int
Explanation
About the Sample Application Code
This C code demonstrates how to configure and handle interrupts on TTL channels using North Atlantic Industries (NAI) hardware components. The code primarily focuses on configuring the interrupts, enabling or disabling them, checking if an interrupt has occurred, and handling user prompts and responses. Below is a detailed breakdown of the code.
Function: configureTTLToInterrupt
Purpose Configures an interrupt for message reception on any TTL channels. This function sets up edge or level triggering for interrupts and specifies the interrupt vectors.
Parameters
- InterruptConfig inputInterruptConfig
: Struct holding configuration for interrupt behavior.
- TtlConfig inputTTLConfig
: Struct holding configuration for TTL channels.
Actions 1. Disables current TTL interrupts. 2. Clears existing interrupt statuses. 3. Sets up interrupt vectors for different status transitions. 4. Configures each channel to trigger interrupts based on edge or level transitions. 5. Specifies how interrupts are steered or directed.
Function: enableTTLInterrupts
Purpose Enables or disables interrupts for specific TTL channels within a defined range.
Parameters
- TtlConfig inputTTLConfig
: Struct defining the range of TTL channels and board specifics.
- bool_t enable
: Flag indicating whether to enable (TRUE
) or disable (FALSE
) interrupts.
Actions - Iterates through the specified channel range and enables or disables the interrupt for different transitions (low-to-high, high-to-low, bit-latched).
Function: basic_ISR_TTL
Purpose Interrupt Service Routine (ISR) for handling TTL interrupts. This function clears the interrupt on the board and sets a flag indicating an interrupt has occurred.
Parameters
- In VxWorks: uint32_t param
(parameter needed for the ISR)
- Otherwise: void *param, uint32_t vector
(parameter and interrupt vector)
Function: checkForTTLInterrupt
Purpose Prompts the user to check if an interrupt has occurred and handles the user response. It gets and prints the status based on the interrupt vector.
Parameters
- TtlConfig inputTTLConfig
: Struct defining the configuration for the TTL channels.
Actions 1. Prompts the user to check for interrupts. 2. Reads the interrupt status and prints it. 3. Optionally clears the status register based on user input.
Function: GetTTLLatchStatusTriggerMode
Purpose Prompts the user to set the trigger mode for the latched status register.
Parameters
- int32_t* interrupt_Edge_Trigger
: Pointer to store the user’s input mode.
Actions - Prompts the user for the mode (edge-triggered or level-triggered) and validates the input.
Function: handleTTLInterrupt
Purpose Handles an occurred TTL interrupt by reading the status and printing relevant information.
Parameters
- uint32_t nVector
: The interrupt vector that has occurred.
Actions 1. Prints a message indicating the occurrence of an interrupt. 2. Based on the interrupt vector, reads and clears the appropriate status. 3. Prints detailed interrupt information like vector and status.
Function: promptUserToClearInterrupt_TTL
Purpose Prompts the user to clear an interrupt.
Actions - Displays a prompt message and awaits the user’s action to clear the interrupt.
Function: DisplayMessage_TTLInterrupt
Purpose Displays messages associated with TTL interrupts based on a given message ID.
Parameters
- int32_t msgId
: Message identifier.
Actions - Switches through predefined message IDs and prints corresponding messages.
Function: printInterruptInformation_TTL
Purpose Prints detailed information about the interrupt, including status and vector/IDR ID.
Parameters
- int32_t interruptID
: ID of the interrupt.
- uint32_t status
: Status register content.
- bool_t isEther
: Flag indicating if the context is Ethernet related.
Actions 1. Prints the interrupt ID or vector. 2. Prints the status.
Function: ClearInterrupt_TTL
Purpose Clears the interrupt status for lo-hi and hi-lo transitions.
Actions 1. Prompts the user to clear the interrupt if needed. 2. Reads and clears the interrupt statuses for different transitions.
File Includes
The code includes several header files necessary for board access, interrupt handling, and TTL configurations, leveraging libraries provided by North Atlantic Industries:
- naiapp_interrupt.h
, naiapp_boardaccess_*
: For common interrupt and board access utilities.
- nai_ttl_int.h
, nai_ttl_cfg.h
: For TTL interrupt and configuration specifics.
- nai.h
, naibrd.h
, naibrd_ether.h
: For board-level operations.
- naibrd_ttl.h
, nai_map_ttl.h
: Specific to TTL functions and mappings.
This code serves as a robust template for setting up and managing TTL interrupts on NAI hardware, ensuring smooth and responsive interaction with the embedded function modules.
#include <stdio.h>
#include <stdlib.h>
/* Common Sample Program include files */
#include "include/naiapp_interrupt.h"
#include "include/naiapp_interrupt_ether.h"
#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 TTL Sample Program include files */
#include "nai_ttl_int.h"
#include "nai_ttl_cfg.h"
/* naibrd include files */
#include "nai.h"
#include "naibrd.h"
#include "naibrd_ether.h"
#include "functions/naibrd_ttl.h"
#include "maps/nai_map_ttl.h"
/**************************************************************************************************************/
/**
<summary>
This function configures an interrupt to occur when a message is received on any of the ttl channels.
</summary>
*/
/**************************************************************************************************************/
void configureTTLToInterrupt(InterruptConfig inputInterruptConfig, TtlConfig inputTTLConfig)
{
int32_t cardIndex = inputTTLConfig.cardIndex;
int32_t module = inputTTLConfig.module;
int32_t interrupt_Edge_Trigger = inputInterruptConfig.interrupt_Edge_Trigger;
int32_t steering = inputInterruptConfig.steering;
uint32_t rawstatus = 0;
int32_t chan;
enableTTLInterrupts(inputTTLConfig, FALSE);
/* Clear the Interrupt Status (Read the status and write back "1" to statuses which are set to clear the status) */
check_status(naibrd_TTL_GetGroupStatusRaw(cardIndex, module, 1, NAI_TTL_STATUS_LO_HI_TRANS_LATCHED, &rawstatus));
check_status(naibrd_TTL_ClearGroupStatusRaw(cardIndex, module, 1, NAI_TTL_STATUS_LO_HI_TRANS_LATCHED, rawstatus));
check_status(naibrd_TTL_GetGroupStatusRaw(cardIndex, module, 1, NAI_TTL_STATUS_HI_LO_TRANS_LATCHED, &rawstatus));
check_status(naibrd_TTL_ClearGroupStatusRaw(cardIndex, module, 1, NAI_TTL_STATUS_HI_LO_TRANS_LATCHED, rawstatus));
check_status(naibrd_TTL_GetGroupStatusRaw(cardIndex, module, 1, NAI_TTL_STATUS_BIT_LATCHED, &rawstatus));
check_status(naibrd_TTL_ClearGroupStatusRaw(cardIndex, module, 1, NAI_TTL_STATUS_BIT_LATCHED, rawstatus));
/* Setup the Interrupt Vector - map to the same vector */
check_status(naibrd_TTL_SetGroupInterruptVector(cardIndex, module, 1, NAI_TTL_STATUS_LO_HI_TRANS_LATCHED, NAI_TTL_LOHI_INTERRUPT_VECTOR));
check_status(naibrd_TTL_SetGroupInterruptVector(cardIndex, module, 1, NAI_TTL_STATUS_HI_LO_TRANS_LATCHED, NAI_TTL_HILO_INTERRUPT_VECTOR));
check_status(naibrd_TTL_SetGroupInterruptVector(cardIndex, module, 1, NAI_TTL_STATUS_BIT_LATCHED, NAI_TTL_BIT_INTERRUPT_VECTOR));
/* Setup the Latched Status Mode */
for (chan = 1; chan <= inputTTLConfig.maxChannel; chan++)
{
check_status(naibrd_TTL_SetEdgeLevelInterrupt(cardIndex, module, chan, NAI_TTL_STATUS_LO_HI_TRANS_LATCHED, (nai_ttl_interrupt_t)interrupt_Edge_Trigger));
check_status(naibrd_TTL_SetEdgeLevelInterrupt(cardIndex, module, chan, NAI_TTL_STATUS_HI_LO_TRANS_LATCHED, (nai_ttl_interrupt_t)interrupt_Edge_Trigger));
check_status(naibrd_TTL_SetEdgeLevelInterrupt(cardIndex, module, chan, NAI_TTL_STATUS_BIT_LATCHED, (nai_ttl_interrupt_t)interrupt_Edge_Trigger));
}
check_status(naibrd_TTL_SetGroupInterruptSteering(cardIndex, module, 1, NAI_TTL_STATUS_LO_HI_TRANS_LATCHED, steering));
check_status(naibrd_TTL_SetGroupInterruptSteering(cardIndex, module, 1, NAI_TTL_STATUS_HI_LO_TRANS_LATCHED, steering));
check_status(naibrd_TTL_SetGroupInterruptSteering(cardIndex, module, 1, NAI_TTL_STATUS_BIT_LATCHED, steering));
}
/**************************************************************************************************************/
/**
<summary>
Enables the channels within the (minChannel,maxChannel) range to interrupt
if enable is true and disables them otherwise.
</summary>
*/
/**************************************************************************************************************/
void enableTTLInterrupts(TtlConfig inputTTLConfig, bool_t enable) {
int32_t channel;
for (channel = inputTTLConfig.minChannel; channel <= inputTTLConfig.maxChannel; channel++)
{
check_status(naibrd_TTL_SetInterruptEnable(inputTTLConfig.cardIndex, inputTTLConfig.module, channel, NAI_TTL_STATUS_LO_HI_TRANS_LATCHED, enable));
check_status(naibrd_TTL_SetInterruptEnable(inputTTLConfig.cardIndex, inputTTLConfig.module, channel, NAI_TTL_STATUS_HI_LO_TRANS_LATCHED, enable));
check_status(naibrd_TTL_SetInterruptEnable(inputTTLConfig.cardIndex, inputTTLConfig.module, channel, NAI_TTL_STATUS_BIT_LATCHED, enable));
}
}
/**************************************************************************************************************/
/**
<summary>
The routine is called to handle a interrupt. This function alerts checkForInterrupt that an interrupt has occurred.
In vxWorks you must clear the Interrupt on the board within the ISR.
</summary>
*/
/**************************************************************************************************************/
#if defined (__VXWORKS__)
void basic_ISR_TTL(uint32_t param)
#else
void basic_ISR_TTL(void *param, uint32_t vector)
#endif
{
interruptOccured = TRUE;
#if defined (__VXWORKS__)
interruptVector = nai_Onboard_GetInterruptVector();
nai_Onboard_ClearInterrupt();
#elif defined (WIN32)
UNREFERENCED_PARAMETER(param);
interruptVector = vector;
#else
interruptVector = vector;
#endif
}
/**************************************************************************************************************/
/**
<summary>
Prompts user to check if an interrupt has occurred. MyIsr() should be installed if using this function.
</summary>
*/
/**************************************************************************************************************/
bool_t checkForTTLInterrupt(TtlConfig inputTTLConfig) {
bool_t bQuit;
int32_t cardIndex;
int32_t module;
uint32_t rawstatus = 0;
int8_t inputBuffer[80];
int32_t inputResponseCnt;
cardIndex = inputTTLConfig.cardIndex;
module = inputTTLConfig.module;
bQuit = FALSE;
interruptOccured = FALSE;
while (!bQuit) {
printf("\nPress enter to check if Lo-Hi or Hi-Lo interrupt Occurred (press Q to quit):");
bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
if (!bQuit) {
if (interruptOccured) {
switch (interruptVector)
{
case NAI_TTL_LOHI_INTERRUPT_VECTOR:
printf("\nLo-Hi Interrupt Occurred");
check_status(naibrd_TTL_GetGroupStatusRaw(cardIndex, module, 1, NAI_TTL_STATUS_LO_HI_TRANS_LATCHED, &rawstatus));
break;
case NAI_TTL_HILO_INTERRUPT_VECTOR:
printf("\nHi-Lo Interrupt Occurred");
check_status(naibrd_TTL_GetGroupStatusRaw(cardIndex, module, 1, NAI_TTL_STATUS_HI_LO_TRANS_LATCHED, &rawstatus));
break;
}
printf("\nVector = %#x \n", interruptVector);
printf("Status = %#x \n", rawstatus);
interruptOccured = FALSE;
}
else {
printf("\nNo Interrupt Occurred");
}
printf("\n\nWould you like to clear the status register? (default:N):");
bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
if (inputBuffer[0] == 'y' || inputBuffer[0] == 'Y')
{
switch (interruptVector)
{
case NAI_TTL_LOHI_INTERRUPT_VECTOR:
check_status(naibrd_TTL_ClearGroupStatusRaw(cardIndex, module, 1, NAI_TTL_STATUS_LO_HI_TRANS_LATCHED, rawstatus));
break;
case NAI_TTL_HILO_INTERRUPT_VECTOR:
check_status(naibrd_TTL_ClearGroupStatusRaw(cardIndex, module, 1, NAI_TTL_STATUS_HI_LO_TRANS_LATCHED, rawstatus));
break;
}
}
}
}
return bQuit;
}
/**************************************************************************************************************/
/**
<summary>
GetTTLLatchStatusTriggerMode handles prompting the user for the trigger mode for the latched status register
(Edge Triggered or Level Triggered).
</summary>
*/
/**************************************************************************************************************/
bool_t GetTTLLatchStatusTriggerMode(int32_t* interrupt_Edge_Trigger)
{
bool_t bQuit;
uint32_t temp;
int8_t inputBuffer[80];
int32_t inputResponseCnt;
printf("\nEnter Latched Status Trigger Mode (Edge=0, Level=1) (Default=0): ");
bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
if (!bQuit)
{
if (inputResponseCnt > 0)
{
temp = (int32_t)atol((const char*)inputBuffer);
if (temp == 0 || temp == 1)
{
*interrupt_Edge_Trigger = temp;
}
else
{
printf("ERROR: Invalid Interrupt Trigger Mode.\n");
}
}
else
*interrupt_Edge_Trigger = 0;
}
return(bQuit);
}
/**************************************************************************************************************/
/**
<summary>
This routine takes in the vector of the TTL RX interrupt that has just occurred. And gets the status, fifo status,
and fifo data of all channels that interrupted, and prints it.
</summary>
*/
/**************************************************************************************************************/
void handleTTLInterrupt(uint32_t nVector) {
uint32_t rawstatus = 0;
printf("\n\nInterrupt Occurred \n\n");
if (inputInterruptConfig.bPromptForInterruptClear)
{
promptUserToClearInterrupt_TTL();
}
switch (nVector)
{
case NAI_TTL_LOHI_INTERRUPT_VECTOR:
printf("LoHi Transition Interrupt\n");
check_status(naibrd_TTL_GetGroupStatusRaw(inputTTLConfig.cardIndex, inputTTLConfig.module, 1, NAI_TTL_STATUS_LO_HI_TRANS_LATCHED, &rawstatus));
check_status(naibrd_TTL_ClearGroupStatusRaw(inputTTLConfig.cardIndex, inputTTLConfig.module, 1, NAI_TTL_STATUS_LO_HI_TRANS_LATCHED, rawstatus));
break;
case NAI_TTL_HILO_INTERRUPT_VECTOR:
printf("HiLo Transition Interrupt\n");
check_status(naibrd_TTL_GetGroupStatusRaw(inputTTLConfig.cardIndex, inputTTLConfig.module, 1, NAI_TTL_STATUS_HI_LO_TRANS_LATCHED, &rawstatus));
check_status(naibrd_TTL_ClearGroupStatusRaw(inputTTLConfig.cardIndex, inputTTLConfig.module, 1, NAI_TTL_STATUS_HI_LO_TRANS_LATCHED, rawstatus));
break;
case NAI_TTL_BIT_INTERRUPT_VECTOR:
printf("BIT Interrupt\n");
check_status(naibrd_TTL_GetGroupStatusRaw(inputTTLConfig.cardIndex, inputTTLConfig.module, 1, NAI_TTL_STATUS_BIT_LATCHED, &rawstatus));
check_status(naibrd_TTL_ClearGroupStatusRaw(inputTTLConfig.cardIndex, inputTTLConfig.module, 1, NAI_TTL_STATUS_BIT_LATCHED, rawstatus));
break;
}
printInterruptInformation_TTL(nVector, rawstatus, FALSE);
}
void promptUserToClearInterrupt_TTL()
{
/* Prompt the user to clear the interrupt received */
SetUserRequestClearInt(FALSE);
printf("\n");
DisplayMessage_TTLInterrupt(MSG_USER_CLEAR_TTL_INT);
/* Wait for the user to respond */
while (!GetUserRequestClearInt())
{
nai_msDelay(10);
}
}
/**************************************************************************************************************/
/**
<summary>
DisplayMessage_TTLInterrupt handles displaying the messages associated with the msgId passed in.
</summary>
*/
/**************************************************************************************************************/
void DisplayMessage_TTLInterrupt(int32_t msgId)
{
switch (msgId)
{
case (int32_t)MSG_BANNER_TTL_INT:
{
printf("\n********************************************************************************");
printf("\n****** TTL INTERRUPT ******");
printf("\nAn interrupt will occur when the TTL Module receives an interrupt status ");
printf("\n********************************************************************************");
}
break;
case (int32_t)MSG_USER_TRIGGER_TTL_INT:
{
printf("\nPress \"Q\" to quit the application.\nPlease trigger TTL Lo-Hi,Hi-Lo or BIT status interrupt:");
}
break;
case (int32_t)MSG_USER_CLEAR_TTL_INT:
{
printf("Press \"C\" to clear interrupts... ");
}
break;
}
}
/**************************************************************************************************************/
/**
<summary>
Function will print the Data provided for each channel that has been set in the status register.
It will also print the status and idr id or vector.
</summary>
*/
/**************************************************************************************************************/
void printInterruptInformation_TTL(int32_t interruptID, uint32_t status, bool_t isEther)
{
printf("-----------------------------------\n");
if (isEther)
printf("\nIDR ID = %#x \n", interruptID);
else
printf("\nVector = %#x \n", interruptID);
printf("Status = %#x \n", status);
}
void ClearInterrupt_TTL()
{
uint32_t status;
if (inputInterruptConfig.bPromptForInterruptClear)
{
promptUserToClearInterrupt_TTL();
}
naibrd_TTL_GetGroupStatusRaw(inputTTLConfig.cardIndex, inputTTLConfig.module, 1, NAI_TTL_STATUS_LO_HI_TRANS_LATCHED, &status);
naibrd_TTL_ClearGroupStatusRaw(inputTTLConfig.cardIndex, inputTTLConfig.module, 1, NAI_TTL_STATUS_LO_HI_TRANS_LATCHED, status);
naibrd_TTL_GetGroupStatusRaw(inputTTLConfig.cardIndex, inputTTLConfig.module, 1, NAI_TTL_STATUS_HI_LO_TRANS_LATCHED, &status);
naibrd_TTL_ClearGroupStatusRaw(inputTTLConfig.cardIndex, inputTTLConfig.module, 1, NAI_TTL_STATUS_HI_LO_TRANS_LATCHED, status);
}