IOCT BasicOps
Edit this on GitLab
IOCT BasicOps Sample Application (SSK 1.x)
Overview
The IOCT BasicOps sample application demonstrates how to configure and operate I/O Control and Timing (IOCT) channels using the NAI Software Support Kit (SSK 1.x). IOCT modules provide high-speed, synchronous serial communication channels designed for deterministic data transfer in embedded systems. At the hardware level, each IOCT channel implements a clocked serial interface with Start-of-Element Pulse (SEP) timing, transmit and receive FIFOs, and configurable master/slave roles — enabling tightly synchronized data exchange between boards or subsystems on a shared bus.
This sample supports the following IOCT module types:
-
PE — Multi-channel IOCT module (
NAI_MODULE_ID_PE,0x5045). -
SC4 — Single-channel Maximillion IOCT module (
NAI_MODULE_ID_SC4,0x53433420).
The SC4 module has a reduced command set compared to the PE: it does not support slave mode, and some command bits (such as even parity and standby mode) differ from their PE equivalents. The sample detects the module type at runtime and loads the appropriate command menu automatically. It serves as a practical API reference — each menu command maps directly to one or more naibrd_IOCT_*() API calls that you can lift into your own code.
Prerequisites
Before running this sample, make sure you have:
-
An NAI board with an IOCT module installed (PE or SC4).
-
SSK 1.x installed on your development host.
-
The sample applications built. Refer to the SSK 1.x build instructions for your platform if you have not already compiled them.
How to Run
Launch the IOCT_BasicOps executable from your build output directory. On startup the application looks for a configuration file (default_IOCT_BasicOps.txt). On the first run, this file will not exist — the application will present an interactive board menu where you configure a board connection, card index, and module slot. You can save this configuration so that subsequent runs skip the menu and connect automatically. Once connected, a command menu lets you exercise each IOCT operation.
Board Connection and Module Selection
|
Note
|
This startup sequence is common to all NAI sample applications. The board connection and module selection code shown here is not specific to IOCT. For details on board connection configuration, see the First Time Setup Guide. |
The main() function follows a standard SSK 1.x startup flow:
-
Call
naiapp_RunBoardMenu()to load a saved configuration file (if one exists) or present the interactive board menu. The configuration file (default_IOCT_BasicOps.txt) is not included with the SSK — it is created when the user saves their connection settings from the board menu. On the first run, the menu will always appear. -
Query the user for a card index with
naiapp_query_CardIndex(). -
Query for a module slot with
naiapp_query_ModuleNumber(). -
Retrieve the module ID with
naibrd_GetModuleID()so downstream code can adapt to the specific IOCT variant installed (PE vs. SC4).
#if defined (__VXWORKS__)
int32_t IOCT_BasicOpsMenu(void)
#else
int32_t main(void)
#endif
{
bool_t stop = FALSE;
int32_t cardIndex;
int32_t moduleCnt;
int32_t module;
uint32_t moduleID = 0;
int8_t inputBuffer[80];
int32_t inputResponseCnt;
if (naiapp_RunBoardMenu(CONFIG_FILE) == TRUE)
{
while (stop != TRUE)
{
stop = naiapp_query_CardIndex(naiapp_GetBoardCnt(), 0, &cardIndex);
if (stop != TRUE)
{
check_status(naibrd_GetModuleCount(cardIndex, &moduleCnt));
stop = naiapp_query_ModuleNumber(moduleCnt, 1, &module);
if (stop != TRUE)
{
moduleID = naibrd_GetModuleID(cardIndex, module);
if ((moduleID != 0))
{
IOCTBasicOpsMenu_run(cardIndex, module, moduleID);
}
}
}
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;
}
|
Important
|
Common connection errors you may encounter at this stage:
|
Program Structure
Entry Point
The main() function (or IOCT_BasicOpsMenu() on VxWorks) handles board connection and module selection as described above. After the user selects a valid module, it calls IOCTBasicOpsMenu_run() to enter the command loop.
Application Parameters
Each command function receives its parameters through a p_naiapp_AppParameters_t structure. In your own code, you will track the same values directly:
-
cardIndex— identifies which board to communicate with (zero-based). -
module— the slot number containing the IOCT module (one-based). -
channel— the IOCT channel to operate on (one-based).
Command Loop and Module-Specific Menus
The IOCTBasicOpsMenu_run() function detects the module type and loads the appropriate command table. For SC4 modules, the slave mode command is omitted because SC4 hardware does not support slave operation. The menu system is a sample convenience — in your own code, call these API functions directly.
static bool_t IOCTBasicOpsMenu_run(int32_t cardIndex, int32_t module, uint32_t modid)
{
bool_t bQuit = FALSE;
int8_t inputBuffer[80];
int32_t inputResponseCnt;
ioct_modid = modid;
if (ioct_modid == NAI_MODULE_ID_SC4)
naiapp_utils_LoadParamMenuCommands(IOCT_BASICOPS_CMD_COUNT,
IOCT_SC4_BasicOpMenuCmds);
else
naiapp_utils_LoadParamMenuCommands(IOCT_BASICOPS_CMD_COUNT,
IOCT_PE_BasicOpMenuCmds);
DisplayIOCTConfigurations(cardIndex, module, modid);
do
{
naiapp_display_ParamMenuCommands((int8_t*)"MENU_TITLE");
bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR,
inputBuffer, &inputResponseCnt);
} while (!bQuit);
return bQuit;
}
The two command tables define the available operations. The PE command table includes all commands; the SC4 table omits the "Slave" entry:
| Menu Key | Description | Module Support |
|---|---|---|
|
Set Master Mode |
PE, SC4 |
|
Set Slave Mode |
PE only |
|
Enable/Disable Loopback |
PE, SC4 |
|
Transmit Data |
PE, SC4 |
|
Receive Data |
PE, SC4 |
|
Display Channel Status |
PE, SC4 |
|
Display Interrupt Status |
PE, SC4 |
|
Clear Interrupt Status |
PE, SC4 |
|
Reset Channel |
PE, SC4 |
|
Clear Tx FIFO |
PE, SC4 |
|
Get Tx FIFO Count |
PE, SC4 |
|
Get Rx FIFO Count |
PE, SC4 |
|
Display Command Register |
PE, SC4 |
Channel Mode Configuration
This section covers the commands that configure the operating role of an IOCT channel: master mode, slave mode, and loopback mode.
Set Master Mode
To configure an IOCT channel as a bus master in your own application, reset the channel first, then set the transmit enable, receive enable, and channel-on bits in the command register. The CfgForIOCTMaster() utility function in nai_ioct_utils.c demonstrates this sequence:
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));
}
The ResetIOCTCfg() utility performs a thorough channel reset before configuration: it issues IOCT_CMD_RESET_CHANNEL, verifies both FIFOs are empty, sets the permitted transmit segment map to all segments (0xFFFF), disables all interrupts, sets interrupts to edge-triggered mode, disables manual SEP mode, and clears all latched interrupt statuses. This ensures the channel starts from a known state.
API parameters:
-
cardIndex,module,channel— identify the target IOCT channel. -
command— a bitmask ofIOCT_CMD_*flags written vianaibrd_IOCT_SetCommand(). For master mode, combineIOCT_CMD_TX_ENABLE | IOCT_CMD_RX_ENABLE | IOCT_CMD_CHANNEL_ON.
Set Slave Mode (PE Only)
To configure a PE channel as a bus slave, the procedure is identical to master mode except that the IOCT_CMD_SLAVE_MODE bit is also set. The SC4 module does not support slave mode — the command is not available in the SC4 menu.
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, transmitter, 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));
}
In slave mode, the channel waits for SEP timing from the bus master rather than generating it locally. The slave transmits only during its permitted transmit segments.
Set Loopback Mode
To enable internal loopback on an IOCT channel — allowing you to transmit and receive data without external cabling — set the IOCT_CMD_LOOPBACK and IOCT_CMD_RX_ALWAYS bits. The CfgForIOCTLoopback() utility reads the current command register, applies or clears the loopback bits, and writes the updated value back:
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));
Loopback mode is useful for verifying your transmit and receive logic before connecting to external hardware. When enabling loopback, the IOCT_CMD_RX_ALWAYS bit must also be set so the receiver accepts data without an external clock source.
|
Important
|
Common Errors
|
Data Transmission and Reception
This section covers the FIFO-based data path: loading transmit data, initiating transmission, and reading received data.
Transmit Data
To transmit data from an IOCT channel, load the data into the Tx FIFO with naibrd_IOCT_SetTxFIFOData(), then trigger transmission with naibrd_IOCT_StartTransmit(). The IOCTXmit() utility function demonstrates the full sequence:
void IOCTXmit(int32_t cardIndex, int32_t module, int32_t channel, int32_t datacnt)
{
uint32_t txcount, datawritten;
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;
}
/* Get the number of elements in the TX FIFO */
check_status(naibrd_IOCT_GetFIFOCount(cardIndex, module, channel,
NAI_IOCT_TX_FIFO, &txcount));
/* Initiate Transmission */
check_status(naibrd_IOCT_StartTransmit(cardIndex, module, channel));
/* Wait for all the elements to be sent out */
while ((txcount != 0) && retry < 10)
{
nai_msDelay(100);
check_status(naibrd_IOCT_GetFIFOCount(cardIndex, module, channel,
NAI_IOCT_TX_FIFO, &txcount));
retry++;
}
}
API parameters:
-
naibrd_IOCT_SetTxFIFOData()—countis the number of 32-bit words to load;data[]is the source array;outwritereturns the number of words actually written. -
naibrd_IOCT_StartTransmit()— triggers the hardware to begin clocking data out of the Tx FIFO. -
naibrd_IOCT_GetFIFOCount()— passNAI_IOCT_TX_FIFOto monitor transmit progress.
The InitializeDataForIOCTXmit() utility prepares the transmit buffer. It generates either a fixed decrementing pattern or random data, then applies the IOCT_SPBITS_MASK to clear reserved protocol bits. It sets the IOCT_CONTROL_MASK bit on the first word (marking it as a control word) and the IOCT_EOB_MASK bit on the last word (marking End-of-Block). The maximum buffer size is MAX_IOCT_DATA_ELEMENTS (100 words). Consult your module’s manual for the actual FIFO depth on your hardware.
Receive Data
To read data received on an IOCT channel, first check the Rx FIFO count with naibrd_IOCT_GetFIFOCount(), then retrieve the data with naibrd_IOCT_GetRxFIFOData(). The IOCTRecv() utility reads the FIFO in chunks:
void IOCTRecv(int32_t cardIndex, int32_t module, int32_t channel)
{
uint32_t rxcount;
uint32_t dataleft, totaldataread, dataread;
uint32_t data[MAX_IOCT_DATA_ELEMENTS];
/* Get the number of elements in the RX FIFO */
check_status(naibrd_IOCT_GetFIFOCount(cardIndex, module, channel,
NAI_IOCT_RX_FIFO, &rxcount));
/* Read elements 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));
dataleft -= dataread;
totaldataread += dataread;
}
}
API parameters:
-
naibrd_IOCT_GetRxFIFOData()—countis the maximum number of words to read;outdata[]receives the data;outreadreturns the number of words actually read. When more data is available than your buffer can hold, read in multiple passes as shown.
|
Important
|
Common Errors
|
Status and Diagnostics
This section covers commands for reading channel status, viewing interrupt status, and clearing latched interrupt flags.
Display Channel Status
To read the operational status of an IOCT channel, call naibrd_IOCT_GetStatus(). The DisplayIOCTStatus() utility iterates over all channels and decodes the status register:
nai_ioct_status_t status;
check_status(naibrd_IOCT_GetStatus(cardIndex, module, channel, &status));
The status register contains the following fields:
-
Bit 4 (
IOCT_STATUS_LAST_CLK_5_MHZ) — indicates whether the last clock detected was 5 MHz (1) or 1.2 MHz (0). -
Bits 3:0 (
IOCT_STATUS_CURRENT_SEG_NUM) — the current segment number on the bus. -
Bit 15 (
IOCT_STATUS_CH_FAULT_LOCKED) — PE only; indicates the channel is fault-locked.
Display Interrupt Status
To read the interrupt status for an IOCT channel, call naibrd_IOCT_GetInterruptStatus() for each group and status type. The DisplayIOCTInterruptStatus() utility reads both realtime and latched statuses for Group A (transmit-side) and Group B (receive-side):
nai_ioct_group_interrupt_t intstatusA, intstatusB;
/* Realtime status */
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));
/* Latched status */
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));
Group A (Tx-side) interrupt flags include: SEP High, SEP Low, Segment 0 Active, EOB Transmitted, Word Transmitted, Tx FIFO Overrun, Tx FIFO Full, and Tx FIFO Empty.
Group B (Rx-side) interrupt flags include: Parity Error, No CLK 100, No SEP, Control Word Received, EOB Received, Word Received, Rx FIFO Overrun, Rx FIFO Full, and Rx FIFO Empty.
Realtime status reflects the current hardware state. Latched status captures events that have occurred since the last clear — use it to detect transient conditions that may no longer be active.
Clear Interrupt Status
To clear latched interrupt flags, the approach differs between PE and SC4 modules. The ClearInterruptStatus() utility handles both:
-
SC4 — call
naibrd_IOCT_ClearInterruptStatus()with a bitmask specifying which flags to clear. You can selectively clear individual bits. -
PE — latched statuses are cleared by reading them. Read the latched status register twice to ensure all latched events are consumed.
/* SC4: selective clear */
check_status(naibrd_IOCT_ClearInterruptStatus(cardIndex, module, channel,
grouptype, clrintstatus));
/* PE: clear-on-read (read twice to catch newly latched events) */
check_status(naibrd_IOCT_GetInterruptStatus(cardIndex, module, channel,
grouptype, NAI_IOCT_INTERRUPT_STATUS_LATCHED, &latched));
check_status(naibrd_IOCT_GetInterruptStatus(cardIndex, module, channel,
grouptype, NAI_IOCT_INTERRUPT_STATUS_LATCHED, &latched));
The QueryForIntStatusClr() utility prompts the user for a channel number and, on SC4, a hex bitmask of bits to clear. On PE modules, all latched statuses are cleared at once.
Display Command Register
To view the current command register configuration for all channels, call naibrd_IOCT_GetCommand() for each channel. The DisplayIOCTConfigurations() utility decodes the individual command bits into a tabular display showing the state of each flag: Manual SEP, 1.2 MHz Clock, Ignore Tx Flow Control, Delay Tx, Inhibit Rx Ready, Omit Tx Parity, Rx Always, No RS485 Termination, Loopback, Tx Enable, Rx Enable, Slave Mode, and Channel On.
nai_ioct_cmd_t command;
check_status(naibrd_IOCT_GetCommand(cardIndex, module, channel, &command));
|
Important
|
Common Errors
|
FIFO Management and Channel Reset
This section covers commands for managing the transmit and receive FIFOs and resetting channels.
Get Tx FIFO Count
To check how many elements are queued in the transmit FIFO, call naibrd_IOCT_GetFIFOCount() with NAI_IOCT_TX_FIFO:
uint32_t fifocount;
check_status(naibrd_IOCT_GetFIFOCount(cardIndex, module, channel,
NAI_IOCT_TX_FIFO, &fifocount));
Get Rx FIFO Count
To check how many elements are available in the receive FIFO, call naibrd_IOCT_GetFIFOCount() with NAI_IOCT_RX_FIFO:
uint32_t fifocount;
check_status(naibrd_IOCT_GetFIFOCount(cardIndex, module, channel,
NAI_IOCT_RX_FIFO, &fifocount));
Clear Tx FIFO
To discard all data in the transmit FIFO without resetting the entire channel, read the current command register and set the IOCT_CMD_CLEAR_TX_FIFO bit:
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));
This preserves all other channel settings (mode, enables, loopback) while clearing only the Tx FIFO contents.
Reset Channel
To perform a full channel reset — clearing both Tx and Rx FIFOs and any partially received or transmitted data — read the current command register and set the IOCT_CMD_RESET_CHANNEL bit:
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));
After a reset, you will need to reconfigure the channel (master/slave mode, enables, etc.) before resuming operation.
|
Important
|
Common Errors
|
Troubleshooting Reference
The following table summarizes the errors and symptoms covered in the preceding sections. Consult your module’s manual for hardware-specific diagnostics and FPGA revision requirements.
| Error / Symptom | Possible Causes | Suggested Resolution |
|---|---|---|
No board found |
Board not powered, cable disconnected, incorrect interface/address in config file. |
Verify physical connections and configuration file settings. |
Connection timeout |
Network misconfiguration, firewall blocking traffic, incorrect bus settings. |
Check IP addresses, firewall rules, and PCI/PCIe bus configuration. |
|
Attempted slave mode on SC4, or used a PE-only command on SC4. |
Check the module type with |
Channel unresponsive after configuration |
|
Ensure the channel-on/standby-off bit is included in the command register write. |
Loopback receive returns no data |
|
Set both |
Tx FIFO write returns fewer words than requested |
FIFO is full. |
Wait for current transmission to complete or clear the Tx FIFO first. |
Transmission never completes |
Channel not in master mode, or slave mode with no external master providing SEP. |
Verify mode configuration. In slave mode, an external master must be active. |
Received data does not match transmitted data |
Protocol bits ( |
Mask received data with |
FIFO count non-zero after reset |
Reset not yet complete. |
Add a brief delay ( |
PE latched interrupt status does not clear |
Clear-on-read semantics; new events latched between reads. |
Read the latched status register twice to consume all pending events. |
SC4 interrupt clear has no effect |
Wrote 0 to bits intended for clearing. |
Write a 1 to each bit you want to clear in the |
Full Source
Full Source — IOCT_BasicOps.c (SSK 1.x)
#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_ioct.h"
#include "advanced/nai_ether_adv.h"
#include "nai_ioct_utils.h"
static const int8_t *CONFIG_FILE = (const int8_t *)"default_IOCT_BasicOps.txt";
/* Function prototypes */
static bool_t IOCTBasicOpsMenu_run(int32_t cardIndex, int32_t module, uint32_t modid);
/* IOCT Command Functions */
static nai_status_t IOCTBasicOpsMenu_commandCfg(int32_t paramCount, int32_t* p_params);
static nai_status_t IOCTBasicOpsMenu_setMaster(int32_t paramCount, int32_t* p_params);
static nai_status_t IOCTBasicOpsMenu_setSlave(int32_t paramCount, int32_t* p_params);
static nai_status_t IOCTBasicOpsMenu_setLoopback(int32_t paramCount, int32_t* p_params);
static nai_status_t IOCTBasicOpsMenu_xmit(int32_t paramCount, int32_t* p_params);
static nai_status_t IOCTBasicOpsMenu_recv(int32_t paramCount, int32_t* p_params);
static nai_status_t IOCTBasicOpsMenu_status(int32_t paramCount, int32_t* p_params);
static nai_status_t IOCTBasicOpsMenu_interruptstatus(int32_t paramCount, int32_t* p_params);
static nai_status_t IOCTBasicOpsMenu_clrinterruptstatus(int32_t paramCount, int32_t* p_params);
static nai_status_t IOCTBasicOpsMenu_reset(int32_t paramCount, int32_t* p_params);
static nai_status_t IOCTBasicOpsMenu_clearTxFifo(int32_t paramCount, int32_t* p_params);
static nai_status_t IOCTBasicOpsMenu_TxFifoCnt(int32_t paramCount, int32_t* p_params);
static nai_status_t IOCTBasicOpsMenu_RxFifoCnt(int32_t paramCount, int32_t* p_params);
/****** Command Table *******/
/* Invariant: enumeration of cmd table starts from 0 and increments by 1 */
enum ioct_BasicOpsMenu_commands
{
IOCT_BASICOPS_CMD_MASTER,
IOCT_BASICOPS_CMD_SLAVE,
IOCT_BASICOPS_CMD_LOOPBACK,
IOCT_BASICOPS_CMD_XMIT,
IOCT_BASICOPS_CMD_RECV,
IOCT_BASICOPS_CMD_STATUS,
IOCT_BASICOPS_CMD_INTSTATUS,
IOCT_BASICOPS_CMD_RESET,
IOCT_BASICOPS_CMD_CLEAR_TX_FIFO,
IOCT_BASICOPS_CMD_TX_FIFO_CNT,
IOCT_BASICOPS_CMD_RX_FIFO_CNT,
IOCT_BASICOPS_CMD_COMMAND_CFG,
IOCT_BASICOPS_CMD_COUNT
};
naiapp_cmdtbl_params_t IOCT_PE_BasicOpMenuCmds[] = {
{"Master", "Set Master Mode", IOCT_BASICOPS_CMD_MASTER, IOCTBasicOpsMenu_setMaster},
{"SLave", "Set Slave Mode", IOCT_BASICOPS_CMD_SLAVE, IOCTBasicOpsMenu_setSlave},
{"Loopback", "Loopback Mode", IOCT_BASICOPS_CMD_LOOPBACK, IOCTBasicOpsMenu_setLoopback},
{"Xmt", "Transmit Data", IOCT_BASICOPS_CMD_XMIT, IOCTBasicOpsMenu_xmit},
{"RCv", "Receive Data", IOCT_BASICOPS_CMD_RECV, IOCTBasicOpsMenu_recv},
{"STatus", "IOCT Status", IOCT_BASICOPS_CMD_STATUS, IOCTBasicOpsMenu_status},
{"IntStat", "Interrupt Status", IOCT_BASICOPS_CMD_INTSTATUS, IOCTBasicOpsMenu_interruptstatus},
{"CLRStat", "Interrupt Status", IOCT_BASICOPS_CMD_INTSTATUS, IOCTBasicOpsMenu_clrinterruptstatus},
{"REset", "Reset Channel", IOCT_BASICOPS_CMD_RESET, IOCTBasicOpsMenu_reset},
{"CLRTx", "Clear Tx Fifo", IOCT_BASICOPS_CMD_CLEAR_TX_FIFO, IOCTBasicOpsMenu_clearTxFifo},
{"TXCnt", "Tx Fifo Count", IOCT_BASICOPS_CMD_TX_FIFO_CNT, IOCTBasicOpsMenu_TxFifoCnt},
{"RXCnt", "Rx Fifo Count", IOCT_BASICOPS_CMD_RX_FIFO_CNT, IOCTBasicOpsMenu_RxFifoCnt},
{"CMd", "Display Command", IOCT_BASICOPS_CMD_COMMAND_CFG, IOCTBasicOpsMenu_commandCfg},
};
/* Note, SC4 cannot be configured as a Slave */
naiapp_cmdtbl_params_t IOCT_SC4_BasicOpMenuCmds[] = {
{"Master", "Set Master Mode", IOCT_BASICOPS_CMD_MASTER, IOCTBasicOpsMenu_setMaster},
{"Loopback", "Loopback Mode", IOCT_BASICOPS_CMD_LOOPBACK, IOCTBasicOpsMenu_setLoopback},
{"Xmt", "Transmit Data", IOCT_BASICOPS_CMD_XMIT, IOCTBasicOpsMenu_xmit},
{"RCv", "Receive Data", IOCT_BASICOPS_CMD_RECV, IOCTBasicOpsMenu_recv},
{"STatus", "IOCT Status", IOCT_BASICOPS_CMD_STATUS, IOCTBasicOpsMenu_status},
{"IntStat", "Interrupt Status", IOCT_BASICOPS_CMD_INTSTATUS, IOCTBasicOpsMenu_interruptstatus},
{"CLRStat", "Interrupt Status", IOCT_BASICOPS_CMD_INTSTATUS, IOCTBasicOpsMenu_clrinterruptstatus},
{"REset", "Reset Channel", IOCT_BASICOPS_CMD_RESET, IOCTBasicOpsMenu_reset},
{"CLRTx", "Clear Tx Fifo", IOCT_BASICOPS_CMD_CLEAR_TX_FIFO, IOCTBasicOpsMenu_clearTxFifo},
{"TXCnt", "Tx Fifo Count", IOCT_BASICOPS_CMD_TX_FIFO_CNT, IOCTBasicOpsMenu_TxFifoCnt},
{"RXCnt", "Rx Fifo Count", IOCT_BASICOPS_CMD_RX_FIFO_CNT, IOCTBasicOpsMenu_RxFifoCnt},
{"CMd", "Display Command", IOCT_BASICOPS_CMD_COMMAND_CFG, IOCTBasicOpsMenu_commandCfg},
};
static uint32_t ioct_modid = 0;
/*****************************************************************************/
/**
<summary>
The purpose of the IOCT_BasicOpsMenu is to illustrate the methods to call in the
naibrd library to perform basic operations with the IOCT modules for
configuration setup and reading the channels.
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 IOCT routines.
- ConfigDevice
- DisplayDeviceCfg
- GetBoardSNModCfg
- CheckModule
</summary>
*/
/*****************************************************************************/
#if defined (__VXWORKS__)
int32_t IOCT_BasicOpsMenu(void)
#else
int32_t main(void)
#endif
{
bool_t stop = FALSE;
int32_t cardIndex;
int32_t moduleCnt;
int32_t module;
uint32_t moduleID = 0;
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))
{
IOCTBasicOpsMenu_run(cardIndex, module, moduleID);
}
}
}
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>
IOCTBasicOpsMenu_run illustrates the channel configuration and prepares the menu
which will handle user command requests. Returns TRUE if the user enters
the Quit Command at any point within its scope.
</summary>
*/
/*****************************************************************************/
static bool_t IOCTBasicOpsMenu_run(int32_t cardIndex, int32_t module, uint32_t modid)
{
bool_t bQuit = FALSE;
int8_t inputBuffer[80];
int32_t inputResponseCnt;
/* int32_t MAX_CHANNELS = naibrd_IOCT_GetChannelCount(modid); */
ioct_modid = modid;
if (ioct_modid == NAI_MODULE_ID_SC4)
naiapp_utils_LoadParamMenuCommands(IOCT_BASICOPS_CMD_COUNT, IOCT_SC4_BasicOpMenuCmds);
else
naiapp_utils_LoadParamMenuCommands(IOCT_BASICOPS_CMD_COUNT, IOCT_PE_BasicOpMenuCmds);
DisplayIOCTConfigurations(cardIndex, module, modid);
do
{
naiapp_display_ParamMenuCommands((int8_t*)"MENU_TITLE");
bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
} while (!bQuit);
return bQuit;
}
/*****************************************************************************/
/**
<summary>
IOCTBasicOpsMenu_commandCfg displays the contents in the command register.
</summary>
*/
/*****************************************************************************/
static nai_status_t IOCTBasicOpsMenu_commandCfg(int32_t paramCount, int32_t* p_params)
{
p_naiapp_AppParameters_t p_ioct_params = (p_naiapp_AppParameters_t)p_params;
int32_t cardIndex = p_ioct_params->cardIndex;
int32_t module = p_ioct_params->module;
#if defined (WIN32)
UNREFERENCED_PARAMETER(paramCount);
#endif
DisplayIOCTConfigurations(cardIndex, module, ioct_modid);
return NAI_ERROR_UNKNOWN;
}
/*****************************************************************************/
/**
<summary>
IOCTBasicOpsMenu_setMaster calls CfgForMaster to configure IOCT channel for
Master mode.
</summary>
*/
/*****************************************************************************/
static nai_status_t IOCTBasicOpsMenu_setMaster(int32_t paramCount, int32_t* p_params)
{
p_naiapp_AppParameters_t p_ioct_params = (p_naiapp_AppParameters_t)p_params;
int32_t cardIndex = p_ioct_params->cardIndex;
int32_t module = p_ioct_params->module;
int32_t channel = p_ioct_params->channel;
#if defined (WIN32)
UNREFERENCED_PARAMETER(paramCount);
#endif
CfgForIOCTMaster(cardIndex, module, channel, ioct_modid);
DisplayIOCTConfigurations(cardIndex, module, ioct_modid);
return NAI_ERROR_UNKNOWN;
}
/*****************************************************************************/
/**
<summary>
IOCTBasicOpsMenu_setSlave calls CfgForMaster to configure IOCT channel for
Slave mode.
</summary>
*/
/*****************************************************************************/
static nai_status_t IOCTBasicOpsMenu_setSlave(int32_t paramCount, int32_t* p_params)
{
p_naiapp_AppParameters_t p_ioct_params = (p_naiapp_AppParameters_t)p_params;
int32_t cardIndex = p_ioct_params->cardIndex;
int32_t module = p_ioct_params->module;
int32_t channel = p_ioct_params->channel;
#if defined (WIN32)
UNREFERENCED_PARAMETER(paramCount);
#endif
CfgForIOCTSlave(cardIndex, module, channel, ioct_modid);
DisplayIOCTConfigurations(cardIndex, module, ioct_modid);
return NAI_ERROR_UNKNOWN;
}
/*****************************************************************************/
/**
<summary>
IOCTBasicOpsMenu_setLoopback calls CfgForIOCTLoopback to query the user on
whether to enable or disable IOCT loopback.
</summary>
*/
/*****************************************************************************/
static nai_status_t IOCTBasicOpsMenu_setLoopback(int32_t paramCount, int32_t* p_params)
{
bool_t bQuit = FALSE;
bool_t loopbackEnabled = FALSE;
p_naiapp_AppParameters_t p_ioct_params = (p_naiapp_AppParameters_t)p_params;
int32_t cardIndex = p_ioct_params->cardIndex;
int32_t module = p_ioct_params->module;
int32_t channel = p_ioct_params->channel;
#if defined (WIN32)
UNREFERENCED_PARAMETER(paramCount);
#endif
bQuit = CfgForIOCTLoopback(cardIndex, module, channel, &loopbackEnabled);
if (!bQuit)
{
DisplayIOCTConfigurations(cardIndex, module, ioct_modid);
}
return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}
/*****************************************************************************/
/**
<summary>
IOCTBasicOpsMenu_xmit handles the user request to transmit data from the IOCT
channel.
</summary>
*/
/*****************************************************************************/
static nai_status_t IOCTBasicOpsMenu_xmit(int32_t paramCount, int32_t* p_params)
{
bool_t bQuit = FALSE;
bool_t bGenRandomData = FALSE;
int32_t datacnt = 0;
p_naiapp_AppParameters_t p_ioct_params = (p_naiapp_AppParameters_t)p_params;
int32_t cardIndex = p_ioct_params->cardIndex;
int32_t module = p_ioct_params->module;
int32_t channel = p_ioct_params->channel;
#if defined (WIN32)
UNREFERENCED_PARAMETER(paramCount);
#endif
bQuit = QueryForIOCTXmitDataCount(&datacnt, &bGenRandomData);
if (!bQuit)
{
InitializeDataForIOCTXmit(datacnt, bGenRandomData);
IOCTXmit(cardIndex, module, channel, datacnt);
}
return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}
/*****************************************************************************/
/**
<summary>
IOCTBasicOpsMenu_recv handles the user request to read the data received on
the IOCT channel.
</summary>
*/
/*****************************************************************************/
static nai_status_t IOCTBasicOpsMenu_recv(int32_t paramCount, int32_t* p_params)
{
p_naiapp_AppParameters_t p_ioct_params = (p_naiapp_AppParameters_t)p_params;
int32_t cardIndex = p_ioct_params->cardIndex;
int32_t module = p_ioct_params->module;
int32_t channel = p_ioct_params->channel;
#if defined (WIN32)
UNREFERENCED_PARAMETER(paramCount);
#endif
IOCTRecv(cardIndex, module, channel);
return NAI_ERROR_UNKNOWN;
}
/*****************************************************************************/
/**
<summary>
IOCTBasicOpsMenu_status handles showing the status information for the IOCT channel.
</summary>
*/
/*****************************************************************************/
static nai_status_t IOCTBasicOpsMenu_status(int32_t paramCount, int32_t* p_params)
{
p_naiapp_AppParameters_t p_ioct_params = (p_naiapp_AppParameters_t)p_params;
int32_t cardIndex = p_ioct_params->cardIndex;
int32_t module = p_ioct_params->module;
#if defined (WIN32)
UNREFERENCED_PARAMETER(paramCount);
#endif
DisplayIOCTStatus(cardIndex, module, ioct_modid);
return NAI_ERROR_UNKNOWN;
}
/*****************************************************************************/
/**
<summary>
IOCTBasicOpsMenu_interruptstatus handles showing the status information for the IOCT channel.
</summary>
*/
/*****************************************************************************/
static nai_status_t IOCTBasicOpsMenu_interruptstatus(int32_t paramCount, int32_t* p_params)
{
p_naiapp_AppParameters_t p_ioct_params = (p_naiapp_AppParameters_t)p_params;
int32_t cardIndex = p_ioct_params->cardIndex;
int32_t module = p_ioct_params->module;
#if defined (WIN32)
UNREFERENCED_PARAMETER(paramCount);
#endif
DisplayIOCTInterruptStatus(cardIndex, module, ioct_modid);
return NAI_ERROR_UNKNOWN;
}
/*****************************************************************************/
/**
<summary>
IOCTBasicOpsMenu_clrinterruptstatus handles queries the user on which interrupt
status to clear.
</summary>
*/
/*****************************************************************************/
static nai_status_t IOCTBasicOpsMenu_clrinterruptstatus(int32_t paramCount, int32_t* p_params)
{
p_naiapp_AppParameters_t p_ioct_params = (p_naiapp_AppParameters_t)p_params;
int32_t cardIndex = p_ioct_params->cardIndex;
int32_t module = p_ioct_params->module;
#if defined (WIN32)
UNREFERENCED_PARAMETER(paramCount);
#endif
DisplayIOCTInterruptStatus(cardIndex, module, ioct_modid);
QueryForIntStatusClr(ioct_modid, cardIndex, module);
return NAI_ERROR_UNKNOWN;
}
/*****************************************************************************/
/**
<summary>
IOCTBasicOpsMenu_reset calls IOCTResetChannel to reset the IOCT channel.
</summary>
*/
/*****************************************************************************/
static nai_status_t IOCTBasicOpsMenu_reset(int32_t paramCount, int32_t* p_params)
{
p_naiapp_AppParameters_t p_ioct_params = (p_naiapp_AppParameters_t)p_params;
int32_t cardIndex = p_ioct_params->cardIndex;
int32_t module = p_ioct_params->module;
int32_t channel = p_ioct_params->channel;
#if defined (WIN32)
UNREFERENCED_PARAMETER(paramCount);
#endif
IOCTResetChannel(cardIndex, module, channel);
return NAI_ERROR_UNKNOWN;
}
/*****************************************************************************/
/**
<summary>
IOCTBasicOpsMenu_clearTxFifo calls IOCTClearTxFifo to clear the Tx FIFO on
the IOCT channel.
</summary>
*/
/*****************************************************************************/
static nai_status_t IOCTBasicOpsMenu_clearTxFifo(int32_t paramCount, int32_t* p_params)
{
p_naiapp_AppParameters_t p_ioct_params = (p_naiapp_AppParameters_t)p_params;
int32_t cardIndex = p_ioct_params->cardIndex;
int32_t module = p_ioct_params->module;
int32_t channel = p_ioct_params->channel;
#if defined (WIN32)
UNREFERENCED_PARAMETER(paramCount);
#endif
IOCTClearTxFifo(cardIndex, module, channel);
return NAI_ERROR_UNKNOWN;
}
/*****************************************************************************/
/**
<summary>
IOCTBasicOpsMenu_TxFifoCnt retrieves the number of elements in the Tx FIFO on
the IOCT channel.
</summary>
*/
/*****************************************************************************/
static nai_status_t IOCTBasicOpsMenu_TxFifoCnt(int32_t paramCount, int32_t* p_params)
{
p_naiapp_AppParameters_t p_ioct_params = (p_naiapp_AppParameters_t)p_params;
int32_t cardIndex = p_ioct_params->cardIndex;
int32_t module = p_ioct_params->module;
int32_t channel = p_ioct_params->channel;
uint32_t fifocount;
#if defined (WIN32)
UNREFERENCED_PARAMETER(paramCount);
#endif
check_status(naibrd_IOCT_GetFIFOCount(cardIndex, module, channel, NAI_IOCT_TX_FIFO, &fifocount));
printf("Tx FIFO Element Count = %d\n", fifocount);
return NAI_ERROR_UNKNOWN;
}
/*****************************************************************************/
/**
<summary>
IOCTBasicOpsMenu_RxFifoCnt retrieves the number of elements in the Rx FIFO on
the IOCT channel.
</summary>
*/
/*****************************************************************************/
static nai_status_t IOCTBasicOpsMenu_RxFifoCnt(int32_t paramCount, int32_t* p_params)
{
p_naiapp_AppParameters_t p_ioct_params = (p_naiapp_AppParameters_t)p_params;
int32_t cardIndex = p_ioct_params->cardIndex;
int32_t module = p_ioct_params->module;
int32_t channel = p_ioct_params->channel;
uint32_t fifocount;
#if defined (WIN32)
UNREFERENCED_PARAMETER(paramCount);
#endif
check_status(naibrd_IOCT_GetFIFOCount(cardIndex, module, channel, NAI_IOCT_RX_FIFO, &fifocount));
printf("Rx FIFO Element Count = %d\n", fifocount);
return NAI_ERROR_UNKNOWN;
}