nai ttl int ether
Edit this on GitLab
nai ttl int ether
Explanation
About the Sample Application Code
The provided code demonstrates how to interact with North Atlantic Industries (NAI) embedded function modules using their System Services Kit (SSK). This specific sample focuses on configuring Interrupt Driven Response (IDR) commands for TTL (Transistor-Transistor Logic) Ethernet interrupts. Let’s walk through the provided code and understand its components and functionality.
Header Inclusions
The sample includes several header files, categorized into common sample program headers, TTL-specific headers, and NAI board-related headers.
#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"
#include "nai_ttl_int_ether.h"
#include "nai_ttl_cfg.h"
#include "functions/naibrd_ttl.h"
#include "maps/nai_map_ttl.h"
#include "advanced/nai_ether_adv.h"
These files collectively provide functions and definitions necessary for handling interrupts and TTL communication over Ethernet.
Functions Overview
void setupIDRConfiguration_TTL(TtlConfig inputTTLConfig, IDRConfig
inputIDRConfig, bool_t bGen4TTLIDRCommands)*
This function configures the IDR commands for the board’s Ethernet interface specific to TTL interrupts. It uses parameters from the TtlConfig
and IDRConfig
structures to set up the commands.
-
Variables:
-
Card settings:
cardIndex
,protocol
,port
,ipAddress
-
Vectors:
vector1
andvector2
for identifying Lo-Hi and Hi-Lo interrupts -
Commands:
commands
,cmdcount
,cmdlength
for storing IDR related data -
Address:
addr
for latched status registers -
Process:
-
Clears existing IDR configuration
-
Initializes new TTL IDR commands
-
Sets IDR configuration for both Lo-Hi and Hi-Lo interrupts
void InitTTLIDRCommands(TtlConfig inputTTLConfig, IDRConfig
inputIDRConfig, bool_t bGen4TTLIDRCommands, uint32_t addr)*
This function initializes the TTL IDR commands by calculating offsets and addresses, then calling the lower-level command-making function if the hardware is capable (bGen4TTLIDRCommands
).
-
Variables:
-
Status and offsets:
status
,boardAddress
,moduleOffset
-
Message index:
msgIndex
-
Process:
-
Retrieves module and board offsets
-
Constructs read command if applicable
void MakeTTLReadRegsCommand(IDRConfig
inputIDRConfig, uint32_t boardAddress, int32_t moduleOffset, bool_t bGen4Ether, uint16_t startIndex, uint32_t addr)*
This function constructs an Ethernet read command to fetch interrupt status registers.
-
Variables:
-
Message index, sequence number:
msgIndex
,seqno
-
Count and stride:
count
,stride
-
Process:
-
Configures command details and adds read message to the IDR configuration
void HandleTTLEtherInterrupt(uint16_t msglen, uint8_t msg[], uint16_t tdr_idr_id)
Called when an Ethernet message with a TDR/IDR index is received. This function decodes the message and processes TTL status interrupts.
-
Variables:
-
Sequence, typecode, size, offset:
seq
,tc
,size
,offset
-
Data and status arrays:
data
,ttlstatus_int
-
Process:
-
Decodes message header
-
Parses the data to extract interrupt status
-
Prints and clears the relevant interrupt status
void MakeTTLWriteRegsCommand(TtlConfig inputTTLConfig, IDRConfig
inputIDRConfig, uint32_t boardAddress, int32_t moduleOffset, bool_t bGen4Ether, uint16_t startIndex)*
This function constructs an Ethernet write command to clear the interrupt status registers and re-arm the interrupts.
-
Variables:
-
Message index, sequence number:
msgIndex
,seqno
-
Count, stride, register address:
count
,stride
,regaddr
-
Data to write:
data
-
Process:
-
Configures command details and adds write message to the IDR configuration
Summary
The provided code configures and handles TTL-related Ethernet interrupts on NAI modules. It sets up the necessary read and write commands to manage the Interrupt Driven Response (IDR) system, ensures accurate handling of interrupts, and then clears and re-arms them as needed.
This comprehensive approach allows for efficient and reliable handling of TTL Ethernet interrupts on NAI’s embedded function modules.
/* 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_ether.h"
#include "nai_ttl_cfg.h"
/* naibrd include files */
#include "functions/naibrd_ttl.h"
#include "maps/nai_map_ttl.h"
#include "advanced/nai_ether_adv.h"
/**************************************************************************************************************/
/**
<summary>
Constructs the ethernet commands that are part of the IDR. Configures the IDR on the board.
</summary>
*/
/**************************************************************************************************************/
void setupIDRConfiguration_TTL(TtlConfig inputTTLConfig, IDRConfig* inputIDRConfig, bool_t bGen4TTLIDRCommands) {
int32_t cardIndex = inputIDRConfig->cardIndex;
uint16_t protocol = inputIDRConfig->protocol;
uint16_t port = inputIDRConfig->port;
uint8_t* ipAddress = inputIDRConfig->ipAddress;
uint8_t ipLength = inputIDRConfig->ipLength;
int32_t vector1 = NAI_TTL_LOHI_INTERRUPT_VECTOR;
int32_t vector2 = NAI_TTL_HILO_INTERRUPT_VECTOR;
uint8_t *commands = inputIDRConfig->commands; /*Stores the ethernet commands that are going to be executed as part of the IDR*/
uint16_t *cmdcount = &inputIDRConfig->cmdcount;
uint16_t *cmdlength = &inputIDRConfig->cmdlength;
uint32_t addr = NAI_TTL_GEN5_REG_LO_HI_TRANS_LATCHED_STATUS_ADD;
check_status(naibrd_Ether_ClearIDRConfig(cardIndex, (uint16_t)DEF_ETHERNET_TTL_LOHI_IDR_ID));/* clear IDR config */
InitTTLIDRCommands(inputTTLConfig, inputIDRConfig, bGen4TTLIDRCommands, addr);
check_status(naibrd_Ether_SetIDRConfig(cardIndex, (uint16_t)DEF_ETHERNET_TTL_LOHI_IDR_ID, protocol, ipLength, ipAddress, port, vector1, *cmdcount, *cmdlength, commands));
check_status(naibrd_Ether_ClearIDRConfig(cardIndex, (uint16_t)DEF_ETHERNET_TTL_HILO_IDR_ID));/* clear IDR config */
check_status(naibrd_Ether_SetIDRConfig(cardIndex, (uint16_t)DEF_ETHERNET_TTL_HILO_IDR_ID, protocol, ipLength, ipAddress, port, vector2, *cmdcount, *cmdlength, commands));
}
/**************************************************************************************************************/
/**
<summary>
This function configures the IDR (Interrupt Driven Response) commands when a TTL Rx interrupt occurs.
There are four Ethernet commands that will be processed by the board when a TTL Rx interrupt occurs.
</summary>
*/
/**************************************************************************************************************/
void InitTTLIDRCommands(TtlConfig inputTTLConfig, IDRConfig* inputIDRConfig, bool_t bGen4TTLIDRCommands, uint32_t addr)
{
nai_status_t status = NAI_SUCCESS;
uint16_t msgIndex = 0;
uint32_t boardAddress;
uint32_t moduleOffset;
boardAddress = 0;
status = check_status(naibrd_GetModuleOffset(inputTTLConfig.cardIndex, inputTTLConfig.module, &moduleOffset));
if (status == NAI_SUCCESS)
status = check_status(naibrd_GetAddress(inputTTLConfig.cardIndex, &boardAddress));
if (status == NAI_SUCCESS)
{
if (bGen4TTLIDRCommands)
{
msgIndex = inputIDRConfig->cmdlength;
MakeTTLReadRegsCommand(inputIDRConfig, boardAddress, moduleOffset, bGen4TTLIDRCommands, msgIndex, addr);
}
}
}
/**************************************************************************************************************/
/**
<summary>
This function constructs an ethernet read reg command and stores it in the IDR Configuration. The read will be performed
on the modules latched status interrupt register. This function will read two registers based on the stride being set to
16 and addr being set to the first register that needs to be read
</summary>
*/
/**************************************************************************************************************/
void MakeTTLReadRegsCommand(IDRConfig* inputIDRConfig, uint32_t boardAddress, int32_t moduleOffset, bool_t bGen4Ether, uint16_t startIndex, uint32_t addr)
{
uint16_t msgIndex = startIndex;
uint16_t seqno;
uint32_t count, stride;
if (bGen4Ether)
{
/*By setting the stride to 16 and base addr sat to Lo-Hi latched status,
two registers will be read using the command array, the Lo-hi and Hi-Lo latched status registers */
seqno = 0;
addr = boardAddress + moduleOffset + addr;
count = TTL_INTERRUPT_RESPONSE_REG_COUNT;
stride = 16;
msgIndex = (uint16_t)nai_ether_MakeReadMessage(&inputIDRConfig->commands[startIndex], seqno, NAI_ETHER_GEN4, (nai_intf_t)inputIDRConfig->boardInterface, addr, stride, count, NAI_REG32);
inputIDRConfig->cmdlength = inputIDRConfig->cmdlength + msgIndex;
command_index_interrupt_status = inputIDRConfig->cmdcount;
inputIDRConfig->cmdcount++;
}
}
/**************************************************************************************************************/
/**
<summary>
HandleTTLEtherInterrupt is called by the decodeUPRIDRMessages() routine in nai_sys_int_ether.c when an
unprompted (UPR) Ethernet message is received with the TDR/IDR Index equal to DEF_ETHERNET_DT_IDR_ID.
This routine will parse the message to retrieve the information requested in the SetupDTEtherIDRconfig()
routine.
</summary>
*/
/**************************************************************************************************************/
void HandleTTLEtherInterrupt(uint16_t msglen, uint8_t msg[], uint16_t tdr_idr_id)
{
uint16_t seq;
nai_ether_typecode_t tc;
nai_ether_gen_t gen = NAI_ETHER_GEN4;
int32_t size;
int32_t offset;
uint16_t datacnt = 0;
uint32_t data;
uint32_t ttlstatus_int[TTL_INTERRUPT_RESPONSE_REG_COUNT];
nai_ttl_status_type_t ttl_status_type = NAI_TTL_STATUS_BIT_LATCHED;
int32_t i;
offset = nai_ether_DecodeMessageHeader(msg, msglen, &seq, &tc, gen, &size);
switch (tc)
{
case NAI_ETHER_TYPECODE_RSP_COMMAND_COMPLETE_READ_4:
datacnt = (msglen - 10) / NAI_REG32;
for (i = 0; i < datacnt; i++)
{
data = 0;
data = msg[offset++] << 24;
data |= msg[offset++] << 16;
data |= msg[offset++] << 8;
data |= msg[offset++];
if (i < TTL_INTERRUPT_RESPONSE_REG_COUNT)
ttlstatus_int[i] = data;
}
break;
}
printf("\n\n");
printf("IDR ID : %d\n", tdr_idr_id);
/* Check to make sure we got all 4 status elements (BIT, Lo-Hi, Hi-Lo, Overcurrent) */
if (datacnt == TTL_INTERRUPT_RESPONSE_REG_COUNT)
{
for (i = 0; i < TTL_INTERRUPT_RESPONSE_REG_COUNT; i++)
{
switch (i)
{
case 0:
ttl_status_type = NAI_TTL_STATUS_LO_HI_TRANS_LATCHED;
break;
case 1:
ttl_status_type = NAI_TTL_STATUS_HI_LO_TRANS_LATCHED;
break;
}
if (ttlstatus_int[i] != 0)
{
switch (i)
{
case 0:
printf("Received TTL Lo-Hi Interrupt: (Interrupt_status) 0x%08X\n", ttlstatus_int[i]);
break;
case 1:
printf("Received TTL Hi-Lo Interrupt: (Interrupt_status) 0x%08X\n", ttlstatus_int[i]);
break;
}
check_status(naibrd_TTL_ClearGroupStatusRaw(inputTTLConfig.cardIndex, inputTTLConfig.module, 1, ttl_status_type, ttlstatus_int[i]));
switch (i)
{
case 0:
printf("Cleared TTL Lo-Hi Interrupt: 0x%08X\n", ttlstatus_int[i]);
break;
case 1:
printf("Cleared TTL Hi-Lo Interrupt: 0x%08X\n", ttlstatus_int[i]);
break;
}
}
}
}
}
/**************************************************************************************************************/
/**
<summary>
This function constructs an ethernet write reg command and stores it in the IDR Configuration. The write will be performed
on the modules latched status interrupt register. The purpose of this write is to clear the interrupt status register and re-arm the interrupts
after one has occurred.
</summary>
*/
/**************************************************************************************************************/
void MakeTTLWriteRegsCommand(TtlConfig inputTTLConfig, IDRConfig* inputIDRConfig, uint32_t boardAddress, int32_t moduleOffset, bool_t bGen4Ether, uint16_t startIndex)
{
uint16_t msgIndex = startIndex;
uint16_t seqno;
uint32_t count, stride;
uint32_t regaddr;
uint32_t data = 0x1 << (inputTTLConfig.channel - 1); /* Clear Rx interrupt bits */
uint32_t addr = NAI_TTL_GEN5_REG_BIT_LATCHED_STATUS_ADD;
if (bGen4Ether)
{
seqno = 0;
regaddr = boardAddress + moduleOffset + addr;
count = 1;
stride = 4;
msgIndex = (uint16_t)nai_ether_BeginWriteMessage(&inputIDRConfig->commands[startIndex], seqno, NAI_ETHER_GEN4, (nai_intf_t)inputIDRConfig->boardInterface, regaddr, stride, count, NAI_REG32);
if (msgIndex >= 0)
{
msgIndex = (uint16_t)nai_ether_WriteMessageData(&inputIDRConfig->commands[startIndex], msgIndex, NAI_REG32, &data, NAI_REG32, count);
if (msgIndex >= 0)
{
msgIndex = (uint16_t)nai_ether_FinishMessage(&inputIDRConfig->commands[startIndex], msgIndex, NAI_ETHER_GEN4);
}
}
inputIDRConfig->cmdlength = inputIDRConfig->cmdlength + msgIndex;
inputIDRConfig->cmdcount++;
}
}