nai ioct utils
Edit this on GitLab
nai ioct utils
Explanation
About the Sample Application Code
This sample application code is designed for use with the North Atlantic Industries (NAI) SSK (Software Support Kit) to interact with their embedded function modules, specifically the IOCT (Input/Output Control and Translation) channels. It demonstrates various functionalities, including displaying configurations, statuses, sending and receiving data, and handling interrupts. Below is a walkthrough and explanation of the code.
Included Header Files The following header files are included, which provide access to various NAI libraries and utilities:
-
Standard C libraries:
<stdio.h>
,<ctype.h>
,<stdlib.h>
,<string.h>
-
NAI sample program files:
-
"include/naiapp_boardaccess_menu.h"
-
"include/naiapp_boardaccess_query.h"
-
"include/naiapp_boardaccess_access.h"
-
"include/naiapp_boardaccess_display.h"
-
"include/naiapp_boardaccess_utils.h"
-
Common IOCT sample program files:
"nai_ioct_utils.h"
-
NAI board include files:
-
"nai.h"
-
"naibrd.h"
-
"functions/naibrd_ioct.h"
-
"advanced/nai_ether_adv.h"
Global Variables
- static uint32_t ioct_data[MAX_IOCT_DATA_ELEMENTS];
- A buffer to hold IOCT data elements.
Function Definitions
Display Functions These functions retrieve and display configuration, status, and interrupt information of IOCT channels.
-
DisplayIOCTConfigurations
-
Retrieves and displays the configuration states for all IOCT channels.
-
Uses
naibrd_IOCT_GetCommand
to get the command value for a channel and prints the bitwise configuration.
-
-
DisplayIOCTStatus
-
Retrieves and displays the status for all IOCT channels.
-
Uses
naibrd_IOCT_GetStatus
to get the status for a channel and prints the bitwise status.
-
-
DisplayIOCTInterruptStatus
-
Retrieves and displays the interrupt status for all IOCT channels.
-
Uses
naibrd_IOCT_GetInterruptStatus
to get real-time and latched interrupt status for both Group A and Group B for each channel.
-
Configuration and Command Functions These functions handle the configuration and command settings for the IOCT channels.
-
ResetIOCTCfg
-
Resets the configuration and interrupt status for an IOCT channel.
-
Uses various library functions to reset FIFOs, clear interrupts, set transmission segments, and disable manual SEP mode.
-
-
CfgForIOCTMaster
-
Configures the IOCT channel as a master.
-
Calls
ResetIOCTCfg
and sets the appropriate command bits for enabling transmitter, receiver, and turning the channel on.
-
-
CfgForIOCTSlave
-
Configures the IOCT channel as a slave.
-
Similar process as
CfgForIOCTMaster
, but also sets the slave mode bit.
-
-
CfgForIOCTLoopback
-
Enables or disables internal loopback mode.
-
Queries user input, updates the command, and sets the loopback and Rx Always bits accordingly.
-
Data Handling Functions These functions manage the data to be transmitted or received through IOCT channels.
-
QueryForIOCTXmitDataCount
-
Queries user for the number of elements to transmit and whether to generate random data.
-
-
InitializeDataForIOCTXmit
-
Initializes the
ioct_data
array with either fixed or random data. -
Ensures the first word is marked as control and the last word as End of Block (EOB).
-
-
IOCTXmit
-
Transmits data through an IOCT channel.
-
Loads data into the TX FIFO and initiates transmission using appropriate library calls.
-
-
IOCTRecv
-
Receives data from an IOCT channel.
-
Reads data from the RX FIFO and displays each received word.
-
-
IOCTResetChannel
-
Resets an IOCT channel by clearing its Tx and Rx FIFOs.
-
-
IOCTClearTxFifo
-
Clears only the Tx FIFO of an IOCT channel.
-
Interrupt Handling Functions These functions manage interrupt statuses for the IOCT channels.
-
QueryForIntStatusClr
-
Queries user input for clearing interrupt statuses for a specified channel.
-
Calls
ClearInterruptStatus
to actually clear the latched and real-time interrupt statuses.
-
-
ClearInterruptStatus
-
Reads and clears the latched and real-time interrupt statuses for a given IOCT channel.
-
Uses the appropriate library functions to clear the specified interrupt bits.
-
Summary This code provides comprehensive examples on how to use the NAI SSK to: - Display IOCT configurations and statuses. - Configure IOCT channels as master, slave, or loopback mode. - Transmit and receive data. - Handle and clear interrupt statuses.
Each function directly interacts with the NAI libraries to perform specific tasks, ensuring real-time control and monitoring of IOCT channels for NAI embedded function modules.
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.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"
/* Common IOCT Sample Program include files */
#include "nai_ioct_utils.h"
/* naibrd include files */
#include "nai.h"
#include "naibrd.h"
#include "functions/naibrd_ioct.h"
#include "advanced/nai_ether_adv.h"
static uint32_t ioct_data[MAX_IOCT_DATA_ELEMENTS];
/*****************************************************************************/
/**
<summary>
DisplayIOCTConfigurations illustrates the methods to call in the naibrd library
to retrieve the basic operation configuration states for all IOCT channels.
</summary>
*/
/*****************************************************************************/
void DisplayIOCTConfigurations(int32_t cardIndex, int32_t module, uint32_t modid)
{
int32_t channel, MAX_CHANNEL = naibrd_IOCT_GetChannelCount(modid);
nai_ioct_cmd_t command;
printf("\n\n");
printf("============================ IOCT Command ====================================\n");
printf(" BIT: 16 13 12 10 9 8 7 6 4 3 2 1 0\n");
printf("Ch Command Man 1.2 Ign Dly Inh Omit Rx No Lpbck Tx Rx Slave Ch\n");
printf(" SEP MHz Tx Tx Rx Tx Always RS485 En En En Mode On\n");
printf(" Clk FC Rdy Parity Term\n");
printf("----------------------------------------------------------------------------------------\n");
for (channel = 1; channel <= MAX_CHANNEL; channel++)
{
check_status(naibrd_IOCT_GetCommand(cardIndex, module, channel, &command));
printf("%02d 0x%04X ", channel, command);
if (command & IOCT_CMD_MANUAL_SEP_CTRL_ENABLE)
printf("1 ");
else
printf("0 ");
if (command & IOCT_CMD_SEL_1_2_MHZ_CLK)
printf("1 ");
else
printf("0 ");
if (command & IOCT_CMD_IGNORE_TX_FLOW_CTRL)
printf("1 ");
else
printf("0 ");
if (command & IOCT_CMD_DELAY_TX)
printf("1 ");
else
printf("0 ");
if (command & IOCT_CMD_INHIBIT_RX_READY)
printf("1 ");
else
printf("0 ");
if (command & IOCT_CMD_OMIT_TX_PARITY)
printf("1 ");
else
printf("0 ");
if (command & IOCT_CMD_RX_ALWAYS)
printf("1 ");
else
printf("0 ");
if (command & IOCT_CMD_NO_RECEIVER_TERM)
printf("1 ");
else
printf("0 ");
if (command & IOCT_CMD_LOOPBACK)
printf("1 ");
else
printf("0 ");
if (command & IOCT_CMD_TX_ENABLE)
printf("1 ");
else
printf("0 ");
if (command & IOCT_CMD_RX_ENABLE)
printf("1 ");
else
printf("0 ");
if (command & IOCT_CMD_SLAVE_MODE)
printf("1 ");
else
printf("0 ");
if (command & IOCT_CMD_CHANNEL_ON)
printf("1 ");
else
printf("0 ");
printf("\n");
}
}
/*****************************************************************************/
/**
<summary>
DisplayIOCTStatus illustrates the methods to call in the naibrd library
to retrieve the status for all IOCT channels.
</summary>
*/
/*****************************************************************************/
void DisplayIOCTStatus(int32_t cardIndex, int32_t module, uint32_t modid)
{
int32_t channel, MAX_CHANNEL = naibrd_IOCT_GetChannelCount(modid);
nai_ioct_status_t status;
printf("\n\n");
printf("======= IOCT Status =========\n");
printf(" BIT: 4 3-0\n");
printf("Ch Status Last Current\n");
printf(" Clk Segment\n");
printf(" 5MHz Number\n");
printf("-------------------------------\n");
for (channel = 1; channel <= MAX_CHANNEL; channel++)
{
check_status(naibrd_IOCT_GetStatus(cardIndex, module, channel, &status));
printf("%02d 0x%04X ", channel, status);
if (status & IOCT_STATUS_LAST_CLK_5_MHZ)
printf("1 ");
else
printf("0 ");
printf("%d", status & IOCT_STATUS_CURRENT_SEG_NUM);
printf("\n");
}
}
/*****************************************************************************/
/**
<summary>
DisplayIOCTInterruptStatus illustrates the methods to call in the naibrd library
to retrieve the interrupt status for all IOCT channels.
</summary>
*/
/*****************************************************************************/
void DisplayIOCTInterruptStatus(int32_t cardIndex, int32_t module, uint32_t modid)
{
int32_t channel, MAX_CHANNEL = naibrd_IOCT_GetChannelCount(modid);
nai_ioct_group_interrupt_t intstatusA, intstatusB, intstatus;
int32_t i;
printf("\n\n");
printf("======================================= IOCT Interrupt Status =================================================\n");
printf(" BIT: 31 29 28 22 21 20 19 18 16 15 14 13 5 4 3 2 0\n");
printf("Ch Status Parity No No Ctrl EOB Word Rx Rx Rx SEP SEP Seg0 EOB Word Tx Tx Tx\n");
printf(" Err Clk SEP Word Rcvd Rcvd FIFO FIFO FIFO High Low Act Xmit Xmit FIFO FIFO FIFO\n");
printf(" 100 Rcvd Over Full Empty Over Full Empty\n");
printf("------------------------------------------------------------------------------------------------------------------------\n");
for (channel = 1; channel <= MAX_CHANNEL; channel++)
{
printf("%02d ", channel);
/* Get Realtime and Latched status for each channel */
for (i = 0; i < 2; i++)
{
if (i == 0)
{
check_status(naibrd_IOCT_GetInterruptStatus(cardIndex, module, channel, NAI_IOCT_GROUP_A, NAI_IOCT_INTERRUPT_STATUS_REALTIME, &intstatusA));
check_status(naibrd_IOCT_GetInterruptStatus(cardIndex, module, channel, NAI_IOCT_GROUP_B, NAI_IOCT_INTERRUPT_STATUS_REALTIME, &intstatusB));
printf("R ");
}
else
{
check_status(naibrd_IOCT_GetInterruptStatus(cardIndex, module, channel, NAI_IOCT_GROUP_A, NAI_IOCT_INTERRUPT_STATUS_LATCHED, &intstatusA));
check_status(naibrd_IOCT_GetInterruptStatus(cardIndex, module, channel, NAI_IOCT_GROUP_B, NAI_IOCT_INTERRUPT_STATUS_LATCHED, &intstatusB));
printf(" L ");
}
intstatus = (intstatusB << 16) | intstatusA;
printf("0x%08X ", intstatus);
/* Group B status */
if (intstatusB & IOCT_GROUP_B_PARITY_ERROR)
printf("1 ");
else
printf("0 ");
if (intstatusB & IOCT_GROUP_B_NO_CLK_100)
printf("1 ");
else
printf("0 ");
if (intstatusB & IOCT_GROUP_B_NO_SEP)
printf("1 ");
else
printf("0 ");
if (intstatusB & IOCT_GROUP_B_CTRL_WORD_RECVD)
printf("1 ");
else
printf("0 ");
if (intstatusB & IOCT_GROUP_B_EOB_RECVD)
printf("1 ");
else
printf("0 ");
if (intstatusB & IOCT_GROUP_B_WORD_RECVD)
printf("1 ");
else
printf("0 ");
if (intstatusB & IOCT_GROUP_B_RX_FIFO_OVERRUN)
printf("1 ");
else
printf("0 ");
if (intstatusB & IOCT_GROUP_B_RX_FIFO_FULL)
printf("1 ");
else
printf("0 ");
if (intstatusB & IOCT_GROUP_B_RX_FIFO_EMPTY)
printf("1 ");
else
printf("0 ");
/* Group A status */
if (intstatusA & IOCT_GROUP_A_SEP_HIGH)
printf("1 ");
else
printf("0 ");
if (intstatusA & IOCT_GROUP_A_SEP_LOW)
printf("1 ");
else
printf("0 ");
if (intstatusA & IOCT_GROUP_A_SEGMENT0_ACTIVE)
printf("1 ");
else
printf("0 ");
if (intstatusA & IOCT_GROUP_A_EOB_XMITTED)
printf("1 ");
else
printf("0 ");
if (intstatusA & IOCT_GROUP_A_WORD_XMITTED)
printf("1 ");
else
printf("0 ");
if (intstatusA & IOCT_GROUP_A_TX_FIFO_OVERRUN)
printf("1 ");
else
printf("0 ");
if (intstatusA & IOCT_GROUP_A_TX_FIFO_FULL)
printf("1 ");
else
printf("0 ");
if (intstatusA & IOCT_GROUP_A_TX_FIFO_EMPTY)
printf("1 ");
else
printf("0 ");
printf("\n");
}
}
}
/*****************************************************************************/
/**
<summary>
ResetIOCTCfg illustrates the methods to call in the naibrd library
to reset the configuration and interrupt status for the ioct channel.
</summary>
*/
/*****************************************************************************/
void ResetIOCTCfg(uint32_t modid, int32_t cardIndex, int32_t module, int32_t channel)
{
uint32_t latched = 0, realtime = 0, intenable = 0;
uint32_t expGroupALatchedStatus = 0, expGroupARealTimeStatus = 0;
uint32_t expGroupBLatchedStatus = 0, expGroupBRealTimeStatus = 0;
uint32_t ignoreGroupAMask, ignoreGroupBMask;
uint32_t fifocount = 0;
/* Reset the channel */
check_status(naibrd_IOCT_SetCommand(cardIndex, module, channel, IOCT_CMD_RESET_CHANNEL));
nai_msDelay(2);
check_status(naibrd_IOCT_GetFIFOCount(cardIndex, module, channel, NAI_IOCT_TX_FIFO, &fifocount));
if (fifocount != 0)
printf("Error: After Ch %d Reset, Tx FIFO count = %d\n", channel, fifocount);
check_status(naibrd_IOCT_GetFIFOCount(cardIndex, module, channel, NAI_IOCT_RX_FIFO, &fifocount));
if (fifocount != 0)
printf("Error: After Ch %d Reset, Rx FIFO count = %d\n", channel, fifocount);
/* Set Transmission Segments Map that are permitted for the IOCT channel */
check_status(naibrd_IOCT_SetPermittedXmitSegMap(cardIndex, module, channel, 0xFFFF));
/* Disable interrupts */
check_status(naibrd_IOCT_SetInterruptEnable(cardIndex, module, channel, NAI_IOCT_GROUP_A, 0x0000));
check_status(naibrd_IOCT_GetInterruptEnable(cardIndex, module, channel, NAI_IOCT_GROUP_A, &intenable));
if (intenable != 0)
printf("Error: Group A enable not cleared, value = 0x%x\n", intenable);
check_status(naibrd_IOCT_SetInterruptEnable(cardIndex, module, channel, NAI_IOCT_GROUP_B, 0x0000));
check_status(naibrd_IOCT_GetInterruptEnable(cardIndex, module, channel, NAI_IOCT_GROUP_B, &intenable));
if (intenable != 0)
printf("Error: Group B enable not cleared, value = 0x%x\n", intenable);
/* Set interrupts to edge trigger */
check_status(naibrd_IOCT_SetEdgeLevelInterrupt(cardIndex, module, channel, NAI_IOCT_EDGE_INTERRUPT));
/* Disable Manual SEP Mode */
check_status(naibrd_IOCT_SetSEPManualMode(cardIndex, module, channel, 0));
/* Clear the interrupt latched statuses */
/* After resetting the configuration and clearing any latched statuses:
The following Group A bits should be set:
IOCT_GROUP_A_TX_FIFO_EMPTY
The following Group A bits should be cleared:
IOCT_GROUP_A_TX_FIFO_FULL
IOCT_GROUP_A_TX_FIFO_OVERRUN
IOCT_GROUP_A_WORD_XMITTED
IOCT_GROUP_A_EOB_XMITTED
The following Group A bits can be in either state:
IOCT_GROUP_A_SEGMENT0_ACTIVE
IOCT_GROUP_A_SEP_LOW
IOCT_GROUP_A_SEP_HIGH
The following Group B bits should be set:
IOCT_GROUP_B_RX_FIFO_EMPTY
The following Group B bits should be cleared:
IOCT_GROUP_B_RX_FIFO_FULL
IOCT_GROUP_B_RX_FIFO_OVERRUN
IOCT_GROUP_B_WORD_RECVD
IOCT_GROUP_B_EOB_RECVD
IOCT_GROUP_B_CTRL_WORD_RECVD
IOCT_GROUP_B_NO_SEP
IOCT_GROUP_B_NO_CLK_100
IOCT_GROUP_B_PARITY_ERROR
The following Group B bits can be in either state:
*/
ignoreGroupAMask = IOCT_GROUP_A_SEP_HIGH | IOCT_GROUP_A_SEP_LOW | IOCT_GROUP_A_SEGMENT0_ACTIVE;
ignoreGroupBMask = 0;
if (modid == NAI_MODULE_ID_SC4)
{
/* For Group A, the following statuses should be set: Tx FIFO Empty, SEP Low */
expGroupALatchedStatus = IOCT_GROUP_A_TX_FIFO_EMPTY;
expGroupARealTimeStatus = IOCT_GROUP_A_TX_FIFO_EMPTY;
/* For Group B, the following statuses should be set: Rx FIFO Empty */
expGroupBLatchedStatus = IOCT_GROUP_B_RX_FIFO_EMPTY;
expGroupBRealTimeStatus = IOCT_GROUP_B_RX_FIFO_EMPTY;
}
else
{
/* Clear the Interrupt Status for Group A and Group B */
/* For Group A, the following statuses should be set: Tx FIFO Empty, SEP Low */
expGroupALatchedStatus = 0;
expGroupARealTimeStatus = IOCT_GROUP_A_TX_FIFO_EMPTY;
/* For Group B, the following statuses should be set: Rx FIFO Empty */
expGroupBLatchedStatus = 0;
expGroupBRealTimeStatus = IOCT_GROUP_B_RX_FIFO_EMPTY;
}
ClearInterruptStatus(modid, cardIndex, module, channel, TRUE, 0xFFFF, &latched, &realtime);
latched = latched & ~ignoreGroupAMask;
realtime = realtime & ~ignoreGroupAMask;
if (latched != expGroupALatchedStatus)
printf("Error: After Ch %d Reset, Group A latched status [actual value = %08X, expect value = %08X]\n", channel, latched, expGroupALatchedStatus);
if (realtime != expGroupARealTimeStatus)
printf("Error: After Ch %d Reset, Group A realtime status [actual value = %08X, expect value = %08X]\n", channel, realtime, expGroupARealTimeStatus);
ClearInterruptStatus(modid, cardIndex, module, channel, FALSE, 0xFFFF, &latched, &realtime);
latched = latched & ~ignoreGroupBMask;
realtime = realtime & ~ignoreGroupBMask;
if (latched != expGroupBLatchedStatus)
printf("Error: After Ch %d Reset, Group B latched status [actual value = %08X, expect value = %08X]\n", channel, latched, expGroupBLatchedStatus);
if (realtime != expGroupBRealTimeStatus)
printf("Error: After Ch %d Reset, Group B realtime status [actual value = %08X, expect value = %08X]\n", channel, realtime, expGroupBRealTimeStatus);
}
/*****************************************************************************/
/**
<summary>
CfgForIOCTMaster illustrates the methods to call in the naibrd library
to configure the ioct channel as master.
</summary>
*/
/*****************************************************************************/
void CfgForIOCTMaster(int32_t cardIndex, int32_t module, int32_t channel, uint32_t modid)
{
nai_ioct_cmd_t command = 0;
ResetIOCTCfg(modid, cardIndex, module, channel);
/* Enable transmitter and receiver and turn channel on */
command = IOCT_CMD_TX_ENABLE | IOCT_CMD_RX_ENABLE | IOCT_CMD_CHANNEL_ON;
check_status(naibrd_IOCT_SetCommand(cardIndex, module, channel, command));
}
/*****************************************************************************/
/**
<summary>
CfgForIOCTSlave illustrates the methods to call in the naibrd library
to configure the ioct channel as slave.
</summary>
*/
/*****************************************************************************/
void CfgForIOCTSlave(int32_t cardIndex, int32_t module, int32_t channel, uint32_t modid)
{
nai_ioct_cmd_t command = 0;
ResetIOCTCfg(modid, cardIndex, module, channel);
/* Enable slave mode, enable transmitter and receiver and turn channel on */
command = IOCT_CMD_SLAVE_MODE | IOCT_CMD_TX_ENABLE | IOCT_CMD_RX_ENABLE | IOCT_CMD_CHANNEL_ON;
check_status(naibrd_IOCT_SetCommand(cardIndex, module, channel, command));
}
/*****************************************************************************/
/**
<summary>
CfgForIOCTLoopback illustrates the methods to call in the naibrd library
to configure the ioct channel for internal loopback. This allows for transmit
and receive for the ioct channel without the need for external cables.
</summary>
*/
/*****************************************************************************/
bool_t CfgForIOCTLoopback(int32_t cardIndex, int32_t module, int32_t channel, bool_t *loopbackEnabled)
{
bool_t bQuit = FALSE;
nai_ioct_cmd_t command = 0;
int8_t inputBuffer[80];
int32_t inputResponseCnt;
printf("Enable Loopback or Type %c to quit : (default: Y) ", NAI_QUIT_CHAR);
bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
if (!bQuit)
{
if (strlen((const char*)inputBuffer) == 0)
*loopbackEnabled = TRUE;
else
{
if ((inputBuffer[0] == 'N') || (inputBuffer[0] == 'n'))
*loopbackEnabled = FALSE;
else
*loopbackEnabled = TRUE;
}
check_status(naibrd_IOCT_GetCommand(cardIndex, module, channel, &command));
if (*loopbackEnabled)
{
/* When in loopback, Rx Always must be set */
command |= (IOCT_CMD_LOOPBACK | IOCT_CMD_RX_ALWAYS);
}
else
command &= ~(IOCT_CMD_LOOPBACK | IOCT_CMD_RX_ALWAYS);
check_status(naibrd_IOCT_SetCommand(cardIndex, module, channel, command));
}
return bQuit;
}
/*****************************************************************************/
/**
<summary>
QueryForIOCTXmitDataCount handles querying the user for the number of elements
to transmit from the ioctl channel and whether to generate random data.
</summary>
*/
/*****************************************************************************/
bool_t QueryForIOCTXmitDataCount(int32_t *datacnt, bool_t *genrandom)
{
bool_t bQuit = FALSE;
int8_t inputBuffer[80];
int32_t inputResponseCnt;
printf("Enter the number of elements to transmit or Type %c to quit : (default: %d) ", NAI_QUIT_CHAR, DEFAULT_XMIT_DATA_CNT);
bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
if (!bQuit)
{
if (strlen((const char*)inputBuffer) == 0)
*datacnt = DEFAULT_XMIT_DATA_CNT;
else
*datacnt = atol((const char*)inputBuffer);
if (*datacnt > 0)
{
printf("Send random data? : (default: N) ");
bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
if (!bQuit)
{
if ((inputBuffer[0] == 'Y') || (inputBuffer[0] == 'y'))
*genrandom = 1;
else
*genrandom = 0;
}
}
}
return bQuit;
}
/*****************************************************************************/
/**
<summary>
InitializeDataForIOCTXmit handles initializes the ioct_data array with either
fixed data or random data if the genrandomdata parameter is set to TRUE.
Note, the control word bit is set for the first word and the EOB bit is set for
the last word. All data elements are masked with SPBITS_MASK to set the
"special" bits to zero.
</summary>
*/
/*****************************************************************************/
int32_t InitializeDataForIOCTXmit(int32_t datacnt, bool_t genrandomdata)
{
int32_t i;
if (datacnt > MAX_IOCT_DATA_ELEMENTS)
datacnt = MAX_IOCT_DATA_ELEMENTS;
if (genrandomdata)
{
for (i = 0; i < datacnt; i++)
{
/* generate random values, mask to make special bits set to zero */
ioct_data[i] = (rand() | (rand() << 16)) & IOCT_SPBITS_MASK;
}
}
else
{
ioct_data[0] = 0xFFFFFFFF & IOCT_SPBITS_MASK;
for (i = 1; i < MAX_IOCT_DATA_ELEMENTS; i++)
{
/* generate random values, mask to make special bits set to zero */
ioct_data[i] = (ioct_data[i-1] - 0x11111111) & IOCT_SPBITS_MASK;
}
}
ioct_data[0] |= IOCT_CONTROL_MASK; /* set the first words as a control word */
ioct_data[datacnt-1] |= IOCT_EOB_MASK; /* set the last word as EOB */
return datacnt;
}
/*****************************************************************************/
/**
<summary>
IOCTXmit illustrates the methods to call in the naibrd library to transmit
the data in ioct_data out the ioct channel.
</summary>
*/
/*****************************************************************************/
void IOCTXmit(int32_t cardIndex, int32_t module, int32_t channel, int32_t datacnt)
{
uint32_t txcount, datawritten;
int32_t i;
int32_t retry = 0;
/* Load data to be transmitted */
check_status(naibrd_IOCT_SetTxFIFOData(cardIndex, module, channel, datacnt, ioct_data, &datawritten));
if ((int32_t)datawritten != datacnt)
{
printf ("ERROR: Only %d elements written instead of %d\n", datawritten, datacnt);
return;
}
printf("Transmitting the following data:\n");
for (i = 0; i < datacnt; i++)
printf("%03d: 0x%X\n", i+1, ioct_data[i]);
/* Get the number of elements in the TX FIFO */
check_status(naibrd_IOCT_GetFIFOCount(cardIndex, module, channel, NAI_IOCT_TX_FIFO, &txcount));
printf("After load, Tx FIFO Element Count = %d\n", txcount);
/* Initiate Transmission */
printf("Start IOCT Transmission ");
check_status(naibrd_IOCT_StartTransmit(cardIndex, module, channel));
/* Wait for all the elements to be sent out */
retry = 0;
while ((txcount != 0) && retry < 10)
{
nai_msDelay(100);
printf(".");
check_status(naibrd_IOCT_GetFIFOCount(cardIndex, module, channel, NAI_IOCT_TX_FIFO, &txcount));
retry++;
}
printf("\nAfter transmission, Tx FIFO Element Count = %d\n", txcount);
}
/*****************************************************************************/
/**
<summary>
IOCTRecv illustrates the methods to call in the naibrd library to retrieve
the data received from the ioct channel.
</summary>
*/
/*****************************************************************************/
void IOCTRecv(int32_t cardIndex, int32_t module, int32_t channel)
{
uint32_t rxcount;
uint32_t dataleft, totaldataread, dataread;
int32_t i;
uint32_t data[MAX_IOCT_DATA_ELEMENTS];
/* Receive Message */
/* Get the number of elements in the RX FIFO */
check_status(naibrd_IOCT_GetFIFOCount(cardIndex, module, channel, NAI_IOCT_RX_FIFO, &rxcount));
printf("Rx Fifo Count: %d\n", rxcount);
/* Get the element from the RX FIFO */
dataleft = rxcount;
totaldataread = 0;
while (dataleft != 0)
{
if (dataleft > MAX_IOCT_DATA_ELEMENTS)
check_status(naibrd_IOCT_GetRxFIFOData(cardIndex, module, channel, MAX_IOCT_DATA_ELEMENTS, &data[0], &dataread));
else
check_status(naibrd_IOCT_GetRxFIFOData(cardIndex, module, channel, dataleft, &data[0], &dataread));
for (i = 0; i < (int)dataread; ++i)
{
totaldataread++;
printf("Word %03d: %08X\n",totaldataread,data[i]);
}
dataleft -= dataread;
}
}
/*****************************************************************************/
/**
<summary>
IOCTResetChannel illustrates the methods to call in the naibrd library to
set the IOCT_CMD_RESET_CHANNEL command. The IOCT_CMD_RESET_CHANNEL command
will clear the channel's Tx and Rx FIFOs, clear any partially received or
transmitted characters.
</summary>
*/
/*****************************************************************************/
void IOCTResetChannel(int32_t cardIndex, int32_t module, int32_t channel)
{
nai_ioct_cmd_t command = 0;
check_status(naibrd_IOCT_GetCommand(cardIndex, module, channel, &command));
command |= IOCT_CMD_RESET_CHANNEL;
check_status(naibrd_IOCT_SetCommand(cardIndex, module, channel, command));
}
/*****************************************************************************/
/**
<summary>
IOCTClearTxFifo illustrates the methods to call in the naibrd library to
set the IOCT_CMD_CLEAR_TX_FIFO command. The IOCT_CMD_CLEAR_TX_FIFO command
will clear the channel's Tx FIFO.
</summary>
*/
/*****************************************************************************/
void IOCTClearTxFifo(int32_t cardIndex, int32_t module, int32_t channel)
{
nai_ioct_cmd_t command = 0;
check_status(naibrd_IOCT_GetCommand(cardIndex, module, channel, &command));
command |= IOCT_CMD_CLEAR_TX_FIFO;
check_status(naibrd_IOCT_SetCommand(cardIndex, module, channel, command));
}
/*****************************************************************************/
/**
<summary>
QueryForIntStatusClr illustrates the methods to call in the naibrd library
to read and clear the latched and realtime interrupt status for the ioct channel.
</summary>
*/
/*****************************************************************************/
void QueryForIntStatusClr(uint32_t modid, int32_t cardIndex, int32_t module)
{
bool_t bQuit = TRUE;
uint32_t clrstatus = 0;
int32_t channel = 1;
uint32_t latched, realtime;
int8_t inputBuffer[80];
int32_t inputResponseCnt;
printf("\nEnter channel or Type %c to quit : (default: 1) ", NAI_QUIT_CHAR);
bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
if (!bQuit)
{
if (strlen((const char*)inputBuffer) == 0)
channel = 1;
else
channel = (int32_t)atol((const char*)inputBuffer);
if ((channel < 0) || (channel > naibrd_IOCT_GetChannelCount(modid)))
bQuit = TRUE;
}
if (!bQuit)
{
if (modid == NAI_MODULE_ID_SC4)
{
printf("Enter the bits (as hex value) to clear or Type %c to quit : (default: 0xFFFFFFFFF (Clear All)) ", NAI_QUIT_CHAR);
bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
if (!bQuit)
{
if (strlen((const char*)inputBuffer) == 0)
clrstatus = 0xFFFFFFFF;
else
clrstatus = (uint32_t)atol((const char*)inputBuffer);
}
}
else
{
printf("All interrupt status will be cleared. Are you sure you want to continue? (default: Y)\n");
if (strlen((const char*)inputBuffer) > 0)
{
if ((inputBuffer[0] == 'n') || (inputBuffer[0] == 'N'))
bQuit = TRUE;
}
}
if (!bQuit)
{
ClearInterruptStatus(modid, cardIndex, module, channel, TRUE, clrstatus & 0x0000FFFF, &latched, &realtime);
ClearInterruptStatus(modid, cardIndex, module, channel, FALSE, (clrstatus >> 16) & 0x0000FFFF, &latched, &realtime);
}
}
}
/*****************************************************************************/
/**
<summary>
ClearInterruptStatus illustrates the methods to call in the naibrd library
to read and clear the latched and realtime interrupt status for the ioct channel.
</summary>
*/
/*****************************************************************************/
void ClearInterruptStatus(uint32_t modid, int32_t cardIndex, int32_t module, int32_t channel, nai_ioct_group_type_t grouptype, uint32_t clrintstatus, uint32_t *latched, uint32_t *realtime)
{
*latched = 0;
*realtime = 0;
if (grouptype == NAI_IOCT_GROUP_A) /* TX Interrupts */
printf("Group A Interrupts:\n");
else if (grouptype == NAI_IOCT_GROUP_B) /* RX Interrupts */
printf("Group B Interrupts:\n");
else
printf("Group A/B Interrupts:\n");
if (modid == NAI_MODULE_ID_SC4)
{
check_status(naibrd_IOCT_GetInterruptStatus(cardIndex, module, channel, grouptype, NAI_IOCT_INTERRUPT_STATUS_LATCHED, latched));
printf("Interrupt Latched Status before Clearing = %08X\n", *latched);
/* Clear Latched Interrupt Status by reading it and writing a 1 to the bits set */
if (clrintstatus != 0)
{
check_status(naibrd_IOCT_ClearInterruptStatus(cardIndex, module, channel, grouptype, clrintstatus));
check_status(naibrd_IOCT_GetInterruptStatus(cardIndex, module, channel, grouptype, NAI_IOCT_INTERRUPT_STATUS_LATCHED, latched));
printf("Interrupt Latched Status after Clearing = %08X\n", *latched);
check_status(naibrd_IOCT_GetInterruptStatus(cardIndex, module, channel, grouptype, NAI_IOCT_INTERRUPT_STATUS_REALTIME, realtime));
printf("Interrupt Realtime Status after Clearing = %08X\n", *realtime);
}
}
else
{
/* Clear Latched Interrupt Status (read twice in case the status are latched) */
check_status(naibrd_IOCT_GetInterruptStatus(cardIndex, module, channel, grouptype, NAI_IOCT_INTERRUPT_STATUS_LATCHED, latched));
printf("Interrupt Latched Status before Clearing = %08X\n", *latched);
check_status(naibrd_IOCT_GetInterruptStatus(cardIndex, module, channel, grouptype, NAI_IOCT_INTERRUPT_STATUS_LATCHED, latched));
printf("Interrupt Latched Status after Clearing = %08X\n", *latched);
/* Clear Realtime Interrupt Status (read twice in case the realtime status are latched) */
check_status(naibrd_IOCT_GetInterruptStatus(cardIndex, module, channel, grouptype, NAI_IOCT_INTERRUPT_STATUS_REALTIME, realtime));
printf("Interrupt Realtime Status before Clearing = %08X\n", *realtime);
check_status(naibrd_IOCT_GetInterruptStatus(cardIndex, module, channel, grouptype, NAI_IOCT_INTERRUPT_STATUS_REALTIME, realtime));
printf("Interrupt Realtime Status after Clearing = %08X\n", *realtime);
}
}