nai rly int ether
Edit this on GitLab
nai rly int ether
Explanation
About This Sample Application Code
This sample application code provided by North Atlantic Industries (NAI) demonstrates how to interact with their embedded function modules through a system known as SSK (Software Support Kit). The code is designed to configure and handle relay (RLY) modules using Ethernet communication. Below is an explanation of different parts of the code, including function definitions, purpose, and usage.
Include Files
The code begins with several #include
directives to import necessary headers required for interrupt handling, Ethernet communication, board access, display utilities, and specific functions related to relay modules.
#include "include/naiapp_interrupt.h"
#include "include/naiapp_interrupt_ether.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_rly_int_ether.h"
#include "nai_rly_cfg.h"
#include "functions/naibrd_rly.h"
#include "maps/nai_map_rly.h"
#include "advanced/nai_ether_adv.h"
setupIDRConfiguration_RLY
This function configures the Interrupt Driven Response (IDR) on the relay board. The IDR allows the board to execute certain commands when an interrupt occurs. The function initializes by clearing any existing IDR configuration and setting up new commands.
Parameters
-
RlyConfig inputRLYConfig
: Configuration structure for the relay module. -
IDRConfig* inputIDRConfig
: Pointer to the IDR configuration. -
bool_t bGen4DSWIDRCommands
: Boolean flag to indicate whether to generate Gen4 DSW IDR commands.
Key Operations
-
Retrieves card index, protocol, port, IP address, etc.
-
Clears previous IDR configuration using
naibrd_Ether_ClearIDRConfig
. -
Initializes relay IDR commands using
InitRLYIDRCommands
. -
Sets new IDR configuration with
naibrd_Ether_SetIDRConfig
.
void setupIDRConfiguration_RLY(RlyConfig inputRLYConfig, IDRConfig* inputIDRConfig, bool_t bGen4DSWIDRCommands) {
...
check_status(naibrd_Ether_ClearIDRConfig(cardIndex, (uint16_t)DEF_ETHERNET_RLY_IDR_ID));
InitRLYIDRCommands(inputRLYConfig, inputIDRConfig, bGen4DSWIDRCommands);
check_status(naibrd_Ether_SetIDRConfig(cardIndex, (uint16_t)DEF_ETHERNET_RLY_IDR_ID, protocol, ipLength, ipAddress, port, vector, *cmdcount, *cmdlength, commands));
}
MakeRLYReadRegsCommand
This function constructs an Ethernet read register command and stores it in the IDR configuration. The command reads the latched status interrupt register on the module.
Parameters
-
IDRConfig* inputIDRConfig
: Pointer to the IDR configuration. -
uint32_t boardAddress
: Board address. -
int32_t moduleOffset
: Offset to the module. -
bool_t bGen4Ether
: Boolean flag for Gen4 Ethernet commands. -
uint16_t startIndex
: Starting index for the commands.
Key Operations
-
Constructs read message using
nai_ether_MakeReadMessage
. -
Updates command length and count in the configuration.
void MakeRLYReadRegsCommand(IDRConfig* inputIDRConfig, uint32_t boardAddress, int32_t moduleOffset, bool_t bGen4Ether, uint16_t startIndex) {
...
if (bGen4Ether) {
...
msgIndex = (uint16_t)nai_ether_MakeReadMessage(&inputIDRConfig->commands[startIndex], seqno, NAI_ETHER_GEN4, (nai_intf_t)inputIDRConfig->boardInterface, regaddr, stride, count, NAI_REG32);
...
}
}
InitRLYIDRCommands
This function configures the IDR commands necessary when a DSW Rx interrupt occurs, ensuring the correct handling of relay module interrupts.
Parameters
-
RlyConfig inputRLYConfig
: Configuration structure for the relay module. -
IDRConfig* inputIDRConfig
: Pointer to the IDR configuration. -
bool_t bGen4DSWIDRCommands
: Boolean flag to indicate whether to generate Gen4 DSW IDR commands.
Key Operations
-
Retrieves board address and module offset.
-
Calls
MakeRLYReadRegsCommand
to create read commands.
void InitRLYIDRCommands(RlyConfig inputRLYConfig, IDRConfig* inputIDRConfig, bool_t bGen4DSWIDRCommands) {
...
status = check_status(naibrd_GetModuleOffset(inputRLYConfig.cardIndex, inputRLYConfig.module, &moduleOffset));
if (status == NAI_SUCCESS) {
status = check_status(naibrd_GetAddress(inputRLYConfig.cardIndex, &boardAddress));
}
if (status == NAI_SUCCESS) {
if (bGen4DSWIDRCommands) {
...
MakeRLYReadRegsCommand(inputIDRConfig, boardAddress, moduleOffset, bGen4DSWIDRCommands, msgIndex);
}
}
}
HandleRLYEtherInterrupt
This function handles Ethernet interrupts for relay modules. It parses the received message and clears any latch status to re-arm the interrupts.
Parameters
-
uint16_t msglen
: Length of the received message. -
uint8_t msg[]
: Array containing the message data. -
uint16_t tdr_idr_id
: IDR ID.
Key Operations
-
Decodes message header using
nai_ether_DecodeMessageHeader
. -
Parses the message based on the type code.
-
Reads the status and clears the interrupt for each channel.
void HandleRLYEtherInterrupt(uint16_t msglen, uint8_t msg[], uint16_t tdr_idr_id) {
...
offset = nai_ether_DecodeMessageHeader(msg, msglen, &seq, &tc, gen, &size);
switch (tc) {
case NAI_ETHER_TYPECODE_RSP_COMMAND_COMPLETE_READ_4:
...
for (chan = 1; chan <= inputRLYConfig.maxChannel; chan++) {
check_status(naibrd_RLY_ClearStatus(inputRLYConfig.cardIndex, inputRLYConfig.module, chan, NAI_RLY_BIT_STATUS_LATCHED));
}
...
break;
}
}
Conclusion
This sample application code is designed to interact with NAI relay modules via Ethernet, handling configuration and interrupt responses effectively. The functions provided facilitate setting up and handling IDR commands, reading registers, and managing interrupts, thereby ensuring smooth operation of the relay modules in an embedded environment.
/* Common Sample Program include files */
#include "include/naiapp_interrupt.h"
#include "include/naiapp_interrupt_ether.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 DSW Sample Program include files */
#include "nai_rly_int_ether.h"
#include "nai_rly_cfg.h"
/* naibrd include files */
#include "functions/naibrd_rly.h"
#include "maps/nai_map_rly.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_RLY(RlyConfig inputRLYConfig, IDRConfig* inputIDRConfig, bool_t bGen4DSWIDRCommands)
{
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 vector = NAI_RLY_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;
check_status(naibrd_Ether_ClearIDRConfig(cardIndex, (uint16_t)DEF_ETHERNET_RLY_IDR_ID)); /* clear IDR config */
InitRLYIDRCommands(inputRLYConfig, inputIDRConfig, bGen4DSWIDRCommands);
check_status(naibrd_Ether_SetIDRConfig(cardIndex, (uint16_t)DEF_ETHERNET_RLY_IDR_ID, protocol, ipLength, ipAddress, port, vector, *cmdcount, *cmdlength, commands));
}
/**************************************************************************************************************/
/**
<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.
</summary>
*/
/**************************************************************************************************************/
void MakeRLYReadRegsCommand(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 addr = NAI_RLY_GEN5_REG_BIT_LATCHED_STATUS_ADD;
if (bGen4Ether)
{
seqno = 0;
regaddr = boardAddress + moduleOffset + addr;
count = RLY_INTERRUPT_RESPONSE_REG_COUNT;
stride = 4;
msgIndex = (uint16_t)nai_ether_MakeReadMessage(&inputIDRConfig->commands[startIndex], seqno, NAI_ETHER_GEN4, (nai_intf_t)inputIDRConfig->boardInterface, regaddr, stride, count, NAI_REG32);
inputIDRConfig->cmdlength = inputIDRConfig->cmdlength + msgIndex;
command_index_interrupt_status = inputIDRConfig->cmdcount;
inputIDRConfig->cmdcount++;
}
}
/**************************************************************************************************************/
/**
<summary>
This function configures the IDR (Interrupt Driven Response) commands when a DSW Rx interrupt occurs.
There are four Ethernet commands that will be processed by the board when a RLY interrupt occurs.
</summary>
*/
/**************************************************************************************************************/
void InitRLYIDRCommands(RlyConfig inputRLYConfig, IDRConfig* inputIDRConfig, bool_t bGen4DSWIDRCommands)
{
nai_status_t status = NAI_SUCCESS;
uint16_t msgIndex = 0;
uint32_t boardAddress;
uint32_t moduleOffset;
boardAddress = 0;
status = check_status(naibrd_GetModuleOffset(inputRLYConfig.cardIndex, inputRLYConfig.module, &moduleOffset));
if (status == NAI_SUCCESS)
status = check_status(naibrd_GetAddress(inputRLYConfig.cardIndex, &boardAddress));
if (status == NAI_SUCCESS)
{
if (bGen4DSWIDRCommands)
{
msgIndex = inputIDRConfig->cmdlength;
MakeRLYReadRegsCommand(inputIDRConfig, boardAddress, moduleOffset, bGen4DSWIDRCommands, msgIndex);
}
}
}
/**************************************************************************************************************/
/**
<summary>
HandleDSWEtherInterrupt 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 HandleRLYEtherInterrupt(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 rlystatus_int[RLY_INTERRUPT_RESPONSE_REG_COUNT];
int32_t i = 0;
int32_t chan = inputRLYConfig.channel;
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 < RLY_INTERRUPT_RESPONSE_REG_COUNT)
rlystatus_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 == RLY_INTERRUPT_RESPONSE_REG_COUNT)
{
printf("\n\n");
if (rlystatus_int[i] != 0)
{
printf("Received RLY Bit Interrupt: (Interrupt_status) 0x%08X\n", rlystatus_int[i]);
/* Clear the status state to re-arm the interrupts */
for (chan = 1; chan <= inputRLYConfig.maxChannel; chan++)
{
/* Clear the Interrupt Status (Read the status and write back "1" to statuses which are set to clear the status) */
check_status(naibrd_RLY_ClearStatus(inputRLYConfig.cardIndex, inputRLYConfig.module, chan, NAI_RLY_BIT_STATUS_LATCHED));
}
printf("Cleared DSW Bit Interrupt: 0x%08X\n", rlystatus_int[i]);
}
}
}