PS BasicOps
Edit this on GitLab
PS BasicOps Sample Application (SSK 1.x)
Overview
The PS BasicOps sample application demonstrates how to monitor the power supply inside an NAI SIU chassis using the NAI Software Support Kit (SSK 1.x). Unlike most NAI sample applications, which exercise I/O modules installed in board slots, this sample communicates directly with the chassis power supply itself. It reads firmware version information, serial number, general and per-rail fault status, and live voltage, current, and temperature measurements across all power rails.
Power supply monitoring matters because the power supply is the foundation of every NAI system. If a rail drifts out of tolerance, every module on the board is affected. The naibrd_PS_*() API gives your application real-time visibility into supply health so you can detect degraded conditions — under-voltage, over-voltage, over-current, or over-temperature — before they cause data corruption or hardware damage. In mission-critical and deployed systems, this monitoring is essential for built-in test (BIT) and predictive maintenance.
The sample targets the PS4 Generation 1 power supply (device name 75PS4_G1). The device identifier NAI_DEV_NAME_PS4G1 is defined in powersupply/naibrd_ps.h. Because the power supply is a board-level device rather than a slot module, the connection model differs from typical NAI samples: you open the device with naibrd_PS_OpenDevice() using a logical card index, not with the standard board menu and module selection flow.
What the Sample Monitors
The PS4 power supply provides multiple internal voltage rails that feed the modules and processors in the chassis:
-
Input — the raw input voltage arriving at the power supply.
-
36 V — the intermediate bus voltage.
-
Battery — battery backup voltage (voltage monitoring only).
-
3.3 V — logic-level supply for FPGAs and digital circuits.
-
5 V — supply for analog front-ends and mixed-signal circuits.
-
12 V — supply for higher-power module subsystems.
-
-12 V — negative supply for bipolar analog circuits.
For each rail the sample reads voltage (last, average, peak, low), current (last, average, peak where available), and temperature (last, average, peak, low where available). It also reads fault status bits that indicate whether any rail has exceeded its safe operating limits.
Prerequisites
Before running this sample, make sure you have:
-
An NAI SIU chassis with a PS4 power supply installed.
-
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.
-
Network connectivity to the chassis (if running externally over Ethernet), or I2C access (if running on the main processor inside the chassis).
How to Run
Launch the PS_BasicOps executable from your build output directory. On startup the application asks whether you are communicating over Ethernet or I2C. If you select Ethernet (the default), it prompts for the IP address, port, and protocol (TCP or UDP). The application then opens a connection to the PS4 power supply, reads all identification, status, and monitor data in a loop, and prints the results to the console. Press Q and Enter to quit, or press Enter alone to refresh the readings.
|
Note
|
This sample does not use a configuration file. The commented-out DEF_CONFIG_FILE line in the source confirms this — connection parameters are entered interactively each time the application runs.
|
Power Supply Connection
|
Note
|
The power supply connection sequence in this sample is different from most NAI sample applications. Instead of using naiapp_RunBoardMenu() to connect to a board and select a module slot, this sample opens the power supply device directly with naibrd_PS_OpenDevice(). The power supply is a board-level device, not a slot module.
|
The main() function follows this startup flow:
-
Display the application description, which explains the two supported communication modes (Ethernet and I2C).
-
Ask the user whether the application is running externally (Ethernet) or on the chassis processor (I2C).
-
If Ethernet: query for IP address, port, and protocol. Call
naibrd_SetIPAddress()to configure the connection, then callnaibrd_PS_OpenDevice()withNAIBRD_COMM_ETHER_TCPorNAIBRD_COMM_ETHER_UDP. -
If I2C: call
naibrd_PS_OpenDevice()withNAIBRD_COMM_I2C. -
If the device opens successfully, enter the monitoring loop. Otherwise, print the error and exit.
-
On exit, call
naibrd_Close()to release the connection.
#if defined (__VXWORKS__)
int32_t PS_BasicOps_Sample(void)
#else
int32_t main(void)
#endif
{
nai_status_t status = NAI_SUCCESS;
bool_t bQuit = FALSE;
bool_t bEthernet = FALSE;
bool_t maximillionBrd = TRUE;
int32_t Protocol = 0, Port = 0;
int8_t szPort[NAI_MAX_PORT_LEN];
int8_t szIPAddress[NAI_MAX_IP_LEN];
int8_t inputBuffer[80];
int32_t inputResponseCnt;
/* ... display banner and application description ... */
DisplayPSApplicationDescription();
/* Check where this application is running */
printf("Is this application running externally and communicating to the SIU\n");
printf("via Ethernet? (default: Y) : ");
bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
if (!bQuit)
{
if ((inputResponseCnt == 0) || (toupper(inputBuffer[0]) == 'Y'))
{
bEthernet = TRUE;
bQuit = naiapp_query_EthernetCfg(maximillionBrd, &Protocol, (int8_t *)&Port, &szIPAddress[0]);
if (!bQuit)
{
sprintf((char*)&szPort[0], "%d", Port);
}
}
}
if (!bQuit)
{
if (bEthernet)
{
check_status(naibrd_SetIPAddress(g_ps_cardIndex, (const char *)&szIPAddress[0], (const char *)&szPort[0]));
if (Protocol == NAI_TCP_PROTOCOL)
{
status = check_status(naibrd_PS_OpenDevice(g_ps_cardIndex, NAIBRD_COMM_ETHER_TCP, NAI_DEV_NAME_PS4G1));
}
else
{
status = check_status(naibrd_PS_OpenDevice(g_ps_cardIndex, NAIBRD_COMM_ETHER_UDP, NAI_DEV_NAME_PS4G1));
}
}
else
{
status = check_status(naibrd_PS_OpenDevice(g_ps_cardIndex, NAIBRD_COMM_I2C, NAI_DEV_NAME_PS4G1));
}
if (status == NAI_SUCCESS)
{
PS_BasicOps();
}
else
{
printf("%s returned status %s\n","naibrd_PS_OpenDevice",nai_GetStatusString(status));
}
naibrd_Close(g_ps_cardIndex);
}
return status;
}
Card Index
The global variable g_ps_cardIndex is set to 5 in this sample. This is a logical reference — it can be any value between 0 and NAI_MAX_CARDS - 1. It does not correspond to a physical slot number. The card index simply identifies this power supply connection within the naibrd library’s internal table. In your own application, choose any unused card index.
static int32_t g_ps_cardIndex = 5;
Communication Modes
To open a connection to the power supply in your own application, call naibrd_PS_OpenDevice() with one of these communication types:
-
NAIBRD_COMM_ETHER_TCP— Ethernet TCP. Use when running on an external host. Requires the NAI Ethernet Listener Server to be running on the main processor in the SIU chassis. -
NAIBRD_COMM_ETHER_UDP— Ethernet UDP. Same requirements as TCP, but uses UDP transport. -
NAIBRD_COMM_I2C— I2C bus. Use when your application runs directly on the main processor inside the SIU chassis (e.g., 75INT2, 75PPC1, 75ARM1).
The third parameter is the device name string. For the PS4 Generation 1 power supply, pass NAI_DEV_NAME_PS4G1 (which resolves to the string "75PS4_G1").
|
Important
|
Common connection errors you may encounter at this stage:
|
Program Structure
Unlike most NAI sample applications, PS BasicOps does not use a menu-driven command loop. Instead, it runs a simple read-and-display loop. Each iteration reads all identification data, all status registers, and all monitor values, prints them to the console, and waits for the user to press Enter (to refresh) or Q (to quit).
The program flow inside PS_BasicOps() is:
-
Read identification — firmware version numbers (master and slave processors), build date, build time, and serial number.
-
Read general status —
ReadStatusGeneral()reads the general status register and its latched counterpart, checking each bit flag against a table of known status conditions. -
Read per-rail fault status —
ReadAllNonGeneralStatuses()reads under-voltage, over-voltage, over-current, and over-temperature status registers (both dynamic and latched) and displays a per-rail fault matrix. -
Read monitors —
ReadAllMonitors()reads live voltage, current, and temperature measurements for every monitored rail.
There is no interactive command selection — the application reads everything on every iteration. This makes the sample useful as a continuous health dashboard for the power supply.
Identification: Version, Build Date, and Serial Number
To retrieve identification information from the power supply, call the properties API functions. These are useful for logging which firmware version is installed, for diagnostics, and for verifying that the power supply is communicating correctly.
Firmware Version
The PS4 power supply has two processors: a master and a slave. To read the firmware version for each processor, call naibrd_PS_GetVersionNum() with NAI_PS_PROC_MASTER or NAI_PS_PROC_SLAVE.
uint8_t majorVer, minorVer, revVer;
if (check_status(naibrd_PS_GetVersionNum(g_ps_cardIndex, NAI_PS_PROC_MASTER, &majorVer, &minorVer, &revVer)) == NAI_SUCCESS)
{
printf(" Master Version: %d.%d.%d ", majorVer, minorVer, revVer);
}
if (check_status(naibrd_PS_GetVersionNum(g_ps_cardIndex, NAI_PS_PROC_SLAVE, &majorVer, &minorVer, &revVer)) == NAI_SUCCESS)
{
printf(" Slave Version: %d.%d.%d ", majorVer, minorVer, revVer);
}
The procType parameter accepts:
-
NAI_PS_PROC_MASTER— the master processor. -
NAI_PS_PROC_SLAVE— the slave processor.
Build Date and Time
To determine when the firmware was built, call naibrd_PS_GetBuildDate() and naibrd_PS_GetBuildTime() for each processor.
uint32_t month, day, year;
uint32_t hour, minute, second;
naibrd_PS_GetBuildDate(g_ps_cardIndex, NAI_PS_PROC_MASTER, &month, &day, &year);
naibrd_PS_GetBuildTime(g_ps_cardIndex, NAI_PS_PROC_MASTER, &hour, &minute, &second);
Serial Number
To read the power supply serial number, call naibrd_PS_GetSerialNum().
uint32_t serialNum;
naibrd_PS_GetSerialNum(g_ps_cardIndex, &serialNum);
|
Important
|
Common errors for identification calls:
|
General Status Monitoring
The general status register reports the health of internal subsystems within the power supply: clock synchronization, serial communication, I2C bus, startup completion, and flash memory integrity. Each condition is represented by a single bit in the status word.
To read the general status in your own application, call naibrd_PS_GetStatus() with PS_STATUS_GENERAL for the dynamic (live) status or PS_STATUS_GENERAL_LATCHED for the latched status. The latched status retains any bit that has been set since the last clear, which is important for detecting transient faults that may have already resolved.
uint32_t dynamicGeneralStatus = 0;
uint32_t latchGeneralStatus = 0;
naibrd_PS_GetStatus(g_ps_cardIndex, PS_STATUS_GENERAL, &dynamicGeneralStatus);
naibrd_PS_GetStatus(g_ps_cardIndex, PS_STATUS_GENERAL_LATCHED, &latchGeneralStatus);
The sample iterates over a table of status bit definitions (status_general_demo_grps[] defined in PS_BasicOps_driven_table.h) and masks each bit from the status word. The table maps human-readable names to their corresponding mask values:
| Status Name | Meaning |
|---|---|
Clock_Master |
Master processor clock status |
Clock_Slave |
Slave processor clock status |
Serial_Master |
Master serial communication status |
Serial_Slave |
Slave serial communication status |
I2c_Master |
Master I2C bus status |
I2c_Slave |
Slave I2C bus status |
Serial_Retry |
Serial communication retry detected |
Success_StartUp |
Startup sequence completed successfully |
Invalid_Flash_Boot |
Boot flash image is invalid |
Invalid_Flash_User |
User flash image is invalid |
Invalid_Flash_Factory |
Factory flash image is invalid |
I2c_5v_Curr_Unconfig |
5V current monitor I2C is unconfigured |
Invalid_Flash_Backup_Boot |
Backup boot flash is invalid |
Invalid_Flash_Backup_User |
Backup user flash is invalid |
Invalid_Flash_Backup_Factory |
Backup factory flash is invalid |
Invalid_Flash_Scratch |
Scratch flash area is invalid |
A value of 1 for a status bit means the condition is active. For error-type bits (Invalid_Flash_*, Serial_Retry), an active bit indicates a problem. For Success_StartUp, an active bit confirms normal operation.
|
Important
|
Common errors for general status monitoring:
|
Per-Rail Fault Status
Beyond the general status, the power supply tracks fault conditions on each individual voltage rail. The ReadAllNonGeneralStatuses() function reads eight separate status registers — dynamic and latched versions of under-voltage, over-voltage, over-current, and over-temperature — and displays a per-rail fault matrix.
To read per-rail fault status in your own application, call naibrd_PS_GetStatus() with the appropriate status type constant:
| Status Type | What It Reports |
|---|---|
|
Active under-voltage conditions |
|
Latched under-voltage conditions |
|
Active over-voltage conditions |
|
Latched over-voltage conditions |
|
Active over-current conditions |
|
Latched over-current conditions |
|
Active over-temperature conditions |
|
Latched over-temperature conditions |
Each status word is a bitmask where individual bits correspond to specific rails. The mask constants are defined in naibrd_ps.h:
uint32_t underVoltageStatus = 0;
uint32_t overVoltageStatus = 0;
uint32_t overCurrentStatus = 0;
naibrd_PS_GetStatus(g_ps_cardIndex, PS_STATUS_UNDER_VOLTAGE, &underVoltageStatus);
naibrd_PS_GetStatus(g_ps_cardIndex, PS_STATUS_OVER_VOLTAGE, &overVoltageStatus);
naibrd_PS_GetStatus(g_ps_cardIndex, PS_STATUS_OVER_CURRENT, &overCurrentStatus);
/* Check the 3.3V rail for under-voltage */
if (underVoltageStatus & PS_STATUS_MONITOR_MASK_VOLT_MONITOR_3_3V)
{
/* 3.3V rail is below acceptable voltage */
}
Rail Mask Constants
| Mask Constant | Rail |
|---|---|
|
3.3 V voltage |
|
5 V voltage |
|
12 V voltage |
|
-12 V voltage |
|
36 V voltage |
|
3.3 V current |
|
5 V current |
|
12 V current |
|
-12 V current |
|
36 V current |
|
5 V temperature |
Per-Rail Availability
Not all fault types apply to all rails. The sample prints "N/A" where a monitor is not available:
| Rail | Voltage Status | Current Status | Temperature Status |
|---|---|---|---|
3.3 V |
Yes |
Yes |
N/A |
5 V |
Yes |
Yes |
Yes |
12 V |
Yes |
Yes |
N/A |
-12 V |
Yes |
Yes |
N/A |
36 V |
Yes |
Yes |
N/A |
Only the 5 V rail has a temperature fault status bit. For the other rails, over-temperature conditions are not monitored at the individual rail level.
|
Important
|
Common errors for per-rail fault status:
|
Voltage, Current, and Temperature Monitors
The ReadAllMonitors() function reads live measurement data from the power supply. This is the core telemetry data that tells you exactly what voltage, current, and temperature each rail is producing at any given moment.
Reading Voltage
To read voltage measurements for a specific rail, call naibrd_PS_GetVoltage(). The function returns an array of values corresponding to the requested monitor masks.
float64_t monitorVoltageArray[4];
naibrd_PS_GetVoltage(g_ps_cardIndex, NAI_PS_VOLT_MONITOR_5V, PS_MONITOR_MASK_ALL, 4, monitorVoltageArray);
/* monitorVoltageArray[0] = last reading
monitorVoltageArray[1] = average
monitorVoltageArray[2] = peak (maximum)
monitorVoltageArray[3] = low (minimum) */
The monType parameter selects the rail:
-
NAI_PS_VOLT_MONITOR_INPUT— input voltage -
NAI_PS_VOLT_MONITOR_36V— 36 V rail -
NAI_PS_VOLT_MONITOR_BATTERY— battery voltage -
NAI_PS_VOLT_MONITOR_3_3V— 3.3 V rail -
NAI_PS_VOLT_MONITOR_5V— 5 V rail -
NAI_PS_VOLT_MONITOR_12V— 12 V rail -
NAI_PS_VOLT_MONITOR_MINUS_12V— -12 V rail
The monMaskWord parameter selects which statistics to retrieve. PS_MONITOR_MASK_ALL requests all four (last, average, peak, low). The maskCount must match the number of bits set in the mask (4 for PS_MONITOR_MASK_ALL).
Reading Current
To read current measurements, call naibrd_PS_GetCurrent(). Current monitoring is available on a subset of rails.
float64_t monitorCurrentArray[3];
naibrd_PS_GetCurrent(g_ps_cardIndex, NAI_PS_CURRENT_MONITOR_5V, PS_MONITOR_MASK_CURR_AVG_PEAK, 3, monitorCurrentArray);
/* monitorCurrentArray[0] = last reading
monitorCurrentArray[1] = average
monitorCurrentArray[2] = peak */
Current monitors use PS_MONITOR_MASK_CURR_AVG_PEAK (last, average, peak — no low value), so the array size is 3. The available current monitor types are:
-
NAI_PS_CURRENT_MONITOR_INPUT— input current -
NAI_PS_CURRENT_MONITOR_3_3V— 3.3 V rail -
NAI_PS_CURRENT_MONITOR_5V— 5 V rail -
NAI_PS_CURRENT_MONITOR_12V— 12 V rail -
NAI_PS_CURRENT_MONITOR_MINUS_12V— -12 V rail
The 36 V and battery rails do not have current monitors.
Reading Temperature
To read temperature measurements, call naibrd_PS_GetTemperature(). Temperature monitoring is only available for selected rails and converter stages.
float64_t monitorTemperatureArray[4];
naibrd_PS_GetTemperature(g_ps_cardIndex, NAI_PS_TEMP_MONITOR_5V, PS_MONITOR_MASK_ALL, 4, monitorTemperatureArray);
/* monitorTemperatureArray[0] = last reading (degrees C)
monitorTemperatureArray[1] = average
monitorTemperatureArray[2] = peak
monitorTemperatureArray[3] = low */
The available temperature monitor types are:
-
NAI_PS_TEMP_MONITOR_INPUT— input stage temperature -
NAI_PS_TEMP_MONITOR_BUCKBOOST— buck/boost converter temperature (associated with the 36 V rail) -
NAI_PS_TEMP_MONITOR_5V— 5 V converter temperature
Temperature values are returned in degrees Celsius.
Monitor Availability by Rail
The following table summarizes which monitors are available for each rail, matching the data the sample reads and displays:
| Rail | Voltage | Current | Temperature |
|---|---|---|---|
Input |
Last, Avg, Peak, Low |
Last, Avg, Peak |
Last, Avg, Peak, Low |
36 V |
Last, Avg, Peak, Low |
N/A |
Buck/Boost (Last, Avg, Peak, Low) |
Battery |
Last, Avg, Peak, Low |
N/A |
N/A |
3.3 V |
Last, Avg, Peak, Low |
Last, Avg, Peak |
N/A |
5 V |
Last, Avg, Peak, Low |
Last, Avg, Peak |
Last, Avg, Peak, Low |
12 V |
Last, Avg, Peak, Low |
Last, Avg, Peak |
N/A |
-12 V |
Last, Avg, Peak, Low |
Last, Avg, Peak |
N/A |
Monitor Mask Values
The monitor mask bits control which statistics are returned in the output array. The array elements are ordered by mask bit position (lowest bit first):
| Mask | Value | Array Index |
|---|---|---|
|
0x01 |
[0] |
|
0x02 |
[1] |
|
0x04 |
[2] |
|
0x08 |
[3] |
The convenience macros combine these masks:
-
PS_MONITOR_MASK_ALL= Last + Average + Peak + Low (4 values) -
PS_MONITOR_MASK_CURR_AVG_PEAK= Last + Average + Peak (3 values)
|
Important
|
Common errors for monitor reads:
|
Utility Functions
The sample uses helper functions defined in PS_BasicOps_utils.c and a data-driven table in PS_BasicOps_driven_table.h to format and display the monitoring data. These are display conveniences — your own application does not need them.
Display Helpers (PS_BasicOps_utils.c)
-
print_ps_status_general_title()/print_ps_status_title()/print_ps_monitor_title()— print column headers for each data section. -
print_ps_status(uint32_t status)— prints1if the status mask is non-zero,0otherwise. This converts a bitmask result into a simple active/inactive indicator. -
print_ps_voltage(float64_t* values, char sign)— prints the four voltage values (last, average, peak, low) with the specified sign character. -
print_ps_current(float64_t* values)— prints the three current values (last, average, peak). -
print_ps_temperature(float64_t* values)— prints the four temperature values as integers in degrees Celsius. -
print_ps_status_na()/print_ps_current_na()/print_ps_temperature_na()— print "N/A" placeholders for rails that do not support a particular monitor type.
Status Table (PS_BasicOps_driven_table.h)
The status_general_demo_grps[] array maps general status bit names to their mask values. The ReadStatusGeneral() function iterates over this table to check and display each status bit without hard-coding the bit positions in the display logic. This pattern makes it easy to add new status bits as the power supply firmware evolves.
Troubleshooting Reference
This section consolidates the errors and diagnostic advice from the preceding sections. Consult your power supply documentation for hardware-specific diagnostics.
| Error / Symptom | Possible Causes | Suggested Resolution |
|---|---|---|
|
Chassis not powered; wrong IP address or port; Ethernet Listener Server not running; wrong communication type selected |
Verify chassis power, network settings, and that the Listener Server is active on the chassis processor. Confirm you are using the correct comm type (Ethernet vs. I2C). |
Connection timeout over Ethernet |
Firewall blocking port; IP address mismatch; network cable disconnected |
Check firewall rules, verify IP address matches chassis configuration, confirm physical network connectivity. |
I2C communication failure |
Application not running on chassis processor; I2C bus misconfigured |
I2C mode only works when running on the main processor inside the SIU chassis. If running externally, use Ethernet. |
All identification fields return zero |
Power supply not responding; connection opened but communication failed |
Reopen the connection. Verify the device name matches your power supply model ( |
Invalid flash status bits set |
Firmware corruption in one or more flash regions |
Contact NAI support for reflashing instructions. The power supply may still operate but behavior could be unpredictable. |
Latched fault bit set but dynamic bit clear |
A transient over-voltage, under-voltage, over-current, or over-temperature condition occurred and resolved |
Investigate whether the condition is recurring. Check input power quality and system load. |
Multiple rails show over/under-voltage simultaneously |
Input power source is unstable or out of specification |
Check the input voltage source. A failing input supply will affect all downstream rails. |
Voltage/current values are all zero |
Power supply has not completed startup; connection dropped |
Check the general status for |
Array size mismatch causes incorrect monitor readings |
|
Use |
Temperature shows N/A for most rails |
Expected behavior — only Input, Buck/Boost, and 5V stages have temperature sensors |
No action needed. This is normal for the PS4 power supply. |
Full Source
Full Source — PS_BasicOps.c (SSK 1.x)
#include <ctype.h>
#include <stdio.h> /* for printf(),getchar() */
#include <string.h> /* for void *memcpy(void *dest, const void *src, size_t n); */
/* 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 "naibrd.h"
#include "nai.h"
#include "powersupply/naibrd_ps.h"
#include "advanced/nai_ether_adv.h"
#include "PS_BasicOps_utils.h"
#include "PS_BasicOps_driven_table.h"
static const int8_t *SAMPLE_PGM_NAME = (const int8_t *)"PS4_BasicOps";
/*static const int8_t *DEF_CONFIG_FILE = (const int8_t *)"default_PS4_BasicOps.txt";*/
/* Global buffer and count for user input */
static int8_t g_ps_op[80];
static int32_t g_ps_responseCnt = 0;
static int32_t g_ps_cardIndex = 5; /* Note, the g_ps_cardIndex is a logical reference to the power supply - can be any value between (0 - NAI_MAX_CARDS-1) */
void DisplayI2CDeviceCfg(void);
void PS_BasicOps(void);
nai_status_t ReadAllNonGeneralStatuses( void );
nai_status_t ReadStatusGeneral( void );
nai_status_t ReadAllMonitors( void );
static void DisplayPSApplicationDescription()
{
printf(" Power Supply Application Description\n");
printf("---------------------------------------------------------------------------------\n");
printf("This application is intended to run with the SIU Chassis that a NAI Power Supply.\n\n");
printf("When this application is running externally from the SIU Chassis,\n");
printf("the NAI Ethernet Listener Server must be running in the main processor\n");
printf("in the NIU SIU Chassis (ex. 75G5, 75INT2, 75PPC1, 75ARM1, etc.),\n");
printf("and the communication method must be Ethernet.\n\n");
printf("When this application is running on the main processor in the NIU SIU Chassis\n");
printf("(ex. 75INT2, 75PPC1, 75ARM1, etc.), the communication method must be I2C.\n\n");
printf("\n");
}
/**************************************************************************************************************/
/**
<summary>
The purpose of the PS_BasicOps is to illustrate the methods to call in the naibrd library to perform basic
monitor operations with the PS4 Power Supply.
</summary>
*/
/**************************************************************************************************************/
#if defined (__VXWORKS__)
int32_t PS_BasicOps_Sample(void)
#else
int32_t main(void)
#endif
{
nai_status_t status = NAI_SUCCESS;
bool_t bQuit = FALSE;
bool_t bEthernet = FALSE;
bool_t maximillionBrd = TRUE;
int32_t Protocol = 0, Port = 0;
int8_t szPort[NAI_MAX_PORT_LEN];
int8_t szIPAddress[NAI_MAX_IP_LEN];
int8_t inputBuffer[80];
int32_t inputResponseCnt;
printf("\n");
printf("NAI Sample Program: %s\n", SAMPLE_PGM_NAME);
printf("=============================================================================\n\n");
DisplayPSApplicationDescription();
/* Check where this application is running */
printf("Is this application running externally and communicating to the SIU\n");
printf("via Ethernet? (default: Y) : ");
bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
if (!bQuit)
{
if ((inputResponseCnt == 0) || (toupper(inputBuffer[0]) == 'Y'))
{
bEthernet = TRUE;
/* Get the IP Address for the NAI board */
bQuit = naiapp_query_EthernetCfg(maximillionBrd, &Protocol, (int8_t *)&Port, &szIPAddress[0]);
if (!bQuit)
{
sprintf((char*)&szPort[0], "%d", Port);
}
}
}
if (!bQuit)
{
if (bEthernet)
{
check_status(naibrd_SetIPAddress(g_ps_cardIndex, (const char *)&szIPAddress[0], (const char *)&szPort[0]));
if (Protocol == NAI_TCP_PROTOCOL)
{
status = check_status(naibrd_PS_OpenDevice(g_ps_cardIndex, NAIBRD_COMM_ETHER_TCP, NAI_DEV_NAME_PS4G1));
}
else
{
status = check_status(naibrd_PS_OpenDevice(g_ps_cardIndex, NAIBRD_COMM_ETHER_UDP, NAI_DEV_NAME_PS4G1));
}
}
else
{
status = check_status(naibrd_PS_OpenDevice(g_ps_cardIndex, NAIBRD_COMM_I2C, NAI_DEV_NAME_PS4G1));
}
if (status == NAI_SUCCESS)
{
PS_BasicOps();
}
else
{
printf("%s returned status %s\n","naibrd_PS_OpenDevice",nai_GetStatusString(status));
printf("Type Enter key to exit program : ");
naiapp_query_ForQuitResponse(sizeof(g_ps_op), NAI_QUIT_CHAR, g_ps_op, &g_ps_responseCnt);
}
/* Close connection to power supply */
naibrd_Close(g_ps_cardIndex);
}
return status;
}
void PS_BasicOps(void)
{
uint32_t serialNum;
uint8_t majorVer, minorVer, revVer;
uint32_t month, day, year;
uint32_t hour, minute, second;
int key_in_value;
do
{
/* Read the FPGA Version Numbers */
if ( check_status( naibrd_PS_GetVersionNum( g_ps_cardIndex, NAI_PS_PROC_MASTER, &majorVer, &minorVer, &revVer ) ) == NAI_SUCCESS )
{
printf(" Master Version: %d.%d.%d ", majorVer, minorVer, revVer);
}
if ( check_status( naibrd_PS_GetVersionNum( g_ps_cardIndex, NAI_PS_PROC_SLAVE, &majorVer, &minorVer, &revVer ) ) == NAI_SUCCESS )
{
printf(" Slave Version: %d.%d.%d ", majorVer, minorVer, revVer);
}
printf("\n");
/* Read Build Date */
if ( check_status( naibrd_PS_GetBuildDate( g_ps_cardIndex, NAI_PS_PROC_MASTER, &month, &day, &year ) )== NAI_SUCCESS )
{
printf( " - Build Date: Master: %02d / %02d /%02d\n",month, day, year );
}
if ( check_status( naibrd_PS_GetBuildDate( g_ps_cardIndex, NAI_PS_PROC_SLAVE, &month, &day, &year ) )== NAI_SUCCESS )
{
printf( " - Build Date: Slave: %02d / %02d /%02d\n",month, day, year );
}
/* Read Build Time */
if ( check_status( naibrd_PS_GetBuildTime( g_ps_cardIndex, NAI_PS_PROC_MASTER, &hour, &minute, &second ) ) == NAI_SUCCESS )
{
printf(" - Build Time: Master: %02u:%02u:%02u\n", hour, minute,second);
}
if ( check_status( naibrd_PS_GetBuildTime( g_ps_cardIndex, NAI_PS_PROC_SLAVE, &hour, &minute, &second ) ) == NAI_SUCCESS )
{
printf(" - Build Time: Slave: %02u:%02u:%02u\n", hour, minute,second);
}
/* Read The Serial Number */
if ( check_status( naibrd_PS_GetSerialNum( g_ps_cardIndex, &serialNum ) ) == NAI_SUCCESS )
{
printf(" - Serial Num: %d\n",serialNum );
}
ReadStatusGeneral();
ReadAllNonGeneralStatuses();
ReadAllMonitors();
printf("press Q/q and \"Enter\" to quit, press \"Enter\" to continue.\n");
key_in_value=getchar();
} while ( key_in_value!='q' && key_in_value!='Q' );
}
nai_status_t ReadStatusGeneral( void )
{
nai_status_t status=NAI_SUCCESS;
uint32_t dynamicGeneralStatus = 0;
uint32_t latchGeneralStatus = 0;
int32_t i;
print_ps_status_general_title();
for ( i=0;i<sizeof(status_general_demo_grps)/sizeof(struct status_general_info);i++ )
{
if (status_general_demo_grps[i].general_mask != PS_STATUS_GENERAL_MASK_NONE )
{
printf("%-36s", status_general_demo_grps[i].grp_name);
status = naibrd_PS_GetStatus( g_ps_cardIndex, PS_STATUS_GENERAL, &dynamicGeneralStatus );
if ( status != NAI_SUCCESS )
{
printf
(
"ERROR: Status %d naibrd_PS_GetStatus(cardIndex=%d,PS_STATUS_GENERAL) **** FAILED ****\n",
status,g_ps_cardIndex);
break;
}
print_ps_status( (dynamicGeneralStatus & status_general_demo_grps[i].general_mask) );
status = naibrd_PS_GetStatus( g_ps_cardIndex, PS_STATUS_GENERAL_LATCHED, &latchGeneralStatus);
if ( status != NAI_SUCCESS )
{
printf
(
"naibrd_PS_GetStatus(cardIndex=%d,PS_STATUS_GENERAL_LATCHED) **** FAILED ****\n",
g_ps_cardIndex);
break;
}
print_ps_status( (latchGeneralStatus & status_general_demo_grps[i].general_mask));
}
else
{
continue;
}
printf("\n");
}
print_ps_short_horizontal_border();
return status;
}
nai_status_t ReadAllNonGeneralStatuses( void )
{
uint32_t underVoltageStatus = 0;
uint32_t overVoltageStatus = 0;
uint32_t overCurrentStatus = 0;
uint32_t overTemperatureStatus = 0;
uint32_t underVoltageLatchStatus = 0;
uint32_t overVoltageLatchStatus = 0;
uint32_t overCurrentLatchStatus = 0;
uint32_t overTemperatureLatchStatus = 0;
nai_status_t status = NAI_SUCCESS;
status = naibrd_PS_GetStatus( g_ps_cardIndex, PS_STATUS_UNDER_VOLTAGE, &underVoltageStatus );
if ( status != NAI_SUCCESS )
{
printf( "naibrd_PS_GetStatus(cardIndex=%d,cmd=PS_STATUS_UNDER_VOLTAGE) **** FAILED ****\n", g_ps_cardIndex);
}
if(status == NAI_SUCCESS)
{
status = naibrd_PS_GetStatus( g_ps_cardIndex, PS_STATUS_OVER_VOLTAGE, &overVoltageStatus );
if ( status != NAI_SUCCESS )
{
printf( "naibrd_PS_GetStatus(cardIndex=%d,cmd=PS_STATUS_OVER_VOLTAGE) **** FAILED ****\n", g_ps_cardIndex);
}
if(status == NAI_SUCCESS)
{
status = naibrd_PS_GetStatus( g_ps_cardIndex, PS_STATUS_OVER_CURRENT, &overCurrentStatus );
if ( status != NAI_SUCCESS )
{
printf( "naibrd_PS_GetStatus(cardIndex=%d,cmd=PS_STATUS_OVER_CURRENT) **** FAILED ****\n", g_ps_cardIndex);
}
if(status == NAI_SUCCESS)
{
status = naibrd_PS_GetStatus( g_ps_cardIndex, PS_STATUS_OVER_TEMPERATURE, &overTemperatureStatus );
if ( status != NAI_SUCCESS )
{
printf( "naibrd_PS_GetStatus(cardIndex=%d,cmd=PS_STATUS_OVER_TEMPERATURE) **** FAILED ****\n", g_ps_cardIndex);
}
if(status == NAI_SUCCESS)
{
status = naibrd_PS_GetStatus( g_ps_cardIndex, PS_STATUS_UNDER_VOLTAGE_LATCHED, &underVoltageLatchStatus );
if ( status != NAI_SUCCESS )
{
printf( "naibrd_PS_GetStatus(cardIndex=%d,cmd=PS_STATUS_UNDER_VOLTAGE_LATCHED) **** FAILED ****\n", g_ps_cardIndex);
}
if(status == NAI_SUCCESS)
{
status = naibrd_PS_GetStatus( g_ps_cardIndex, PS_STATUS_OVER_VOLTAGE_LATCHED, &overVoltageLatchStatus );
if ( status != NAI_SUCCESS )
{
printf( "naibrd_PS_GetStatus(cardIndex=%d,cmd=PS_STATUS_OVER_VOLTAGE_LATCHED) **** FAILED ****\n", g_ps_cardIndex);
}
if(status == NAI_SUCCESS)
{
status = naibrd_PS_GetStatus( g_ps_cardIndex, PS_STATUS_OVER_CURRENT_LATCHED, &overCurrentLatchStatus );
if ( status != NAI_SUCCESS )
{
printf( "naibrd_PS_GetStatus(cardIndex=%d,cmd=PS_STATUS_OVER_CURRENT_LATCHED) **** FAILED ****\n", g_ps_cardIndex);
}
if(status == NAI_SUCCESS)
{
status = naibrd_PS_GetStatus( g_ps_cardIndex, PS_STATUS_OVER_TEMPERATURE_LATCHED, &overTemperatureLatchStatus );
if ( status != NAI_SUCCESS )
{
printf( "naibrd_PS_GetStatus(cardIndex=%d,cmd=PS_STATUS_OVER_TEMPERATURE_LATCHED) **** FAILED ****\n", g_ps_cardIndex);
}
}
}
}
}
}
}
}
if ( status == NAI_SUCCESS )
{
print_ps_status_title();
printf("%-16s", VOLT_3_3_NAME);
print_ps_status(underVoltageStatus & PS_STATUS_MONITOR_MASK_VOLT_MONITOR_3_3V);
print_ps_status(underVoltageLatchStatus & PS_STATUS_MONITOR_MASK_VOLT_MONITOR_3_3V);
print_ps_status(overVoltageStatus & PS_STATUS_MONITOR_MASK_VOLT_MONITOR_3_3V);
print_ps_status(overVoltageLatchStatus & PS_STATUS_MONITOR_MASK_VOLT_MONITOR_3_3V);
print_ps_status(overCurrentStatus & PS_STATUS_MONITOR_MASK_CURRENT_MONITOR_3_3V);
print_ps_status(overCurrentLatchStatus & PS_STATUS_MONITOR_MASK_CURRENT_MONITOR_3_3V);
print_ps_status_na(); /*There is no temp status for 3.3V*/
print_ps_status_na(); /*There is no temp status for 3.3V*/
printf("\n");
printf("%-16s", VOLT_5_NAME);
print_ps_status(underVoltageStatus & PS_STATUS_MONITOR_MASK_VOLT_MONITOR_5V);
print_ps_status(underVoltageLatchStatus & PS_STATUS_MONITOR_MASK_VOLT_MONITOR_5V);
print_ps_status(overVoltageStatus & PS_STATUS_MONITOR_MASK_VOLT_MONITOR_5V);
print_ps_status(overVoltageLatchStatus & PS_STATUS_MONITOR_MASK_VOLT_MONITOR_5V);
print_ps_status(overCurrentStatus & PS_STATUS_MONITOR_MASK_CURRENT_MONITOR_5V);
print_ps_status(overCurrentLatchStatus & PS_STATUS_MONITOR_MASK_CURRENT_MONITOR_5V);
print_ps_status(overTemperatureStatus & PS_STATUS_MONITOR_MASK_TEMP_MONITOR_5V);
print_ps_status(overTemperatureLatchStatus & PS_STATUS_MONITOR_MASK_TEMP_MONITOR_5V);
printf("\n");
printf("%-16s", VOLT_12_NAME);
print_ps_status(underVoltageStatus & PS_STATUS_MONITOR_MASK_VOLT_MONITOR_12V);
print_ps_status(underVoltageLatchStatus & PS_STATUS_MONITOR_MASK_VOLT_MONITOR_12V);
print_ps_status(overVoltageStatus & PS_STATUS_MONITOR_MASK_VOLT_MONITOR_12V);
print_ps_status(overVoltageLatchStatus & PS_STATUS_MONITOR_MASK_VOLT_MONITOR_12V);
print_ps_status(overCurrentStatus & PS_STATUS_MONITOR_MASK_CURRENT_MONITOR_12V);
print_ps_status(overCurrentLatchStatus & PS_STATUS_MONITOR_MASK_CURRENT_MONITOR_12V);
print_ps_status_na(); /*There is no temp status for 12V*/
print_ps_status_na(); /*There is no temp status for 12V*/
printf("\n");
printf("%-16s", VOLT_MINUS_12_NAME);
print_ps_status(underVoltageStatus & PS_STATUS_MONITOR_MASK_VOLT_MONITOR_MINUS_12V);
print_ps_status(underVoltageLatchStatus & PS_STATUS_MONITOR_MASK_VOLT_MONITOR_MINUS_12V);
print_ps_status(overVoltageStatus & PS_STATUS_MONITOR_MASK_VOLT_MONITOR_MINUS_12V);
print_ps_status(overVoltageLatchStatus & PS_STATUS_MONITOR_MASK_VOLT_MONITOR_MINUS_12V);
print_ps_status(overCurrentStatus & PS_STATUS_MONITOR_MASK_CURRENT_MONITOR_MINUS_12V);
print_ps_status(overCurrentLatchStatus & PS_STATUS_MONITOR_MASK_CURRENT_MONITOR_MINUS_12V);
print_ps_status_na(); /*There is no temp status for -12V*/
print_ps_status_na(); /*There is no temp status for -12V*/
printf("\n");
printf("%-16s", VOLT_36_NAME);
print_ps_status(underVoltageStatus & PS_STATUS_MONITOR_MASK_VOLT_MONITOR_36V);
print_ps_status(underVoltageLatchStatus & PS_STATUS_MONITOR_MASK_VOLT_MONITOR_36V);
print_ps_status(overVoltageStatus & PS_STATUS_MONITOR_MASK_VOLT_MONITOR_36V);
print_ps_status(overVoltageLatchStatus & PS_STATUS_MONITOR_MASK_VOLT_MONITOR_36V);
print_ps_status(overCurrentStatus & PS_STATUS_MONITOR_MASK_CURRENT_MONITOR_36V);
print_ps_status(overCurrentLatchStatus & PS_STATUS_MONITOR_MASK_CURRENT_MONITOR_36V);
print_ps_status_na(); /*There is no temp status for 36V*/
print_ps_status_na(); /*There is no temp status for 36V*/
printf("\n");
print_ps_long_horizontal_border();
}
return status;
}
nai_status_t ReadAllMonitors( void )
{
nai_status_t status;
float64_t monitorVoltageArray[4];
float64_t monitorCurrentArray[3];
float64_t monitorTemperatureArray[4];
print_ps_monitor_title();
printf("%-16s", VOLT_INPUT_NAME);
status = naibrd_PS_GetVoltage( g_ps_cardIndex, NAI_PS_VOLT_MONITOR_INPUT, PS_MONITOR_MASK_ALL, 4, monitorVoltageArray );
if( status == NAI_SUCCESS)
{
print_ps_voltage(monitorVoltageArray ,'+');
}
status = naibrd_PS_GetCurrent( g_ps_cardIndex, NAI_PS_CURRENT_MONITOR_INPUT, PS_MONITOR_MASK_CURR_AVG_PEAK, 3, monitorCurrentArray );
if( status == NAI_SUCCESS)
{
print_ps_current(monitorCurrentArray);
}
status = naibrd_PS_GetTemperature( g_ps_cardIndex, NAI_PS_TEMP_MONITOR_INPUT, PS_MONITOR_MASK_ALL, 4, monitorTemperatureArray );
if( status == NAI_SUCCESS)
{
print_ps_temperature(monitorTemperatureArray);
}
printf("\n");
printf("%-16s", VOLT_36_NAME);
status = naibrd_PS_GetVoltage( g_ps_cardIndex, NAI_PS_VOLT_MONITOR_36V, PS_MONITOR_MASK_ALL, 4, monitorVoltageArray );
if( status == NAI_SUCCESS)
{
print_ps_voltage(monitorVoltageArray ,'+');
}
if( status == NAI_SUCCESS)
{
print_ps_current_na();
}
status = naibrd_PS_GetTemperature( g_ps_cardIndex, NAI_PS_TEMP_MONITOR_BUCKBOOST, PS_MONITOR_MASK_ALL, 4, monitorTemperatureArray );
if( status == NAI_SUCCESS)
{
print_ps_temperature(monitorTemperatureArray);
}
printf("\n");
printf("%-16s", VOLT_BATTERY_NAME);
status = naibrd_PS_GetVoltage( g_ps_cardIndex, NAI_PS_VOLT_MONITOR_BATTERY, PS_MONITOR_MASK_ALL, 4, monitorVoltageArray );
if( status == NAI_SUCCESS)
{
print_ps_voltage(monitorVoltageArray ,'+');
}
if( status == NAI_SUCCESS)
{
print_ps_current_na();
}
if( status == NAI_SUCCESS)
{
print_ps_temperature_na();
}
printf("\n");
printf("%-16s", VOLT_3_3_NAME);
status = naibrd_PS_GetVoltage( g_ps_cardIndex, NAI_PS_VOLT_MONITOR_3_3V, PS_MONITOR_MASK_ALL, 4, monitorVoltageArray );
if( status == NAI_SUCCESS)
{
print_ps_voltage(monitorVoltageArray ,'+');
}
status = naibrd_PS_GetCurrent( g_ps_cardIndex, NAI_PS_CURRENT_MONITOR_3_3V, PS_MONITOR_MASK_CURR_AVG_PEAK, 3, monitorCurrentArray );
if( status == NAI_SUCCESS)
{
print_ps_current(monitorCurrentArray);
}
print_ps_temperature_na();
printf("\n");
printf("%-16s", VOLT_5_NAME);
status = naibrd_PS_GetVoltage( g_ps_cardIndex, NAI_PS_VOLT_MONITOR_5V, PS_MONITOR_MASK_ALL, 4, monitorVoltageArray );
if( status == NAI_SUCCESS)
{
print_ps_voltage(monitorVoltageArray ,'+');
}
status = naibrd_PS_GetCurrent( g_ps_cardIndex, NAI_PS_CURRENT_MONITOR_5V, PS_MONITOR_MASK_CURR_AVG_PEAK, 3, monitorCurrentArray );
if( status == NAI_SUCCESS)
{
print_ps_current(monitorCurrentArray);
}
status = naibrd_PS_GetTemperature( g_ps_cardIndex, NAI_PS_TEMP_MONITOR_5V, PS_MONITOR_MASK_ALL, 4, monitorTemperatureArray );
if( status == NAI_SUCCESS)
{
print_ps_temperature(monitorTemperatureArray);
}
printf("\n");
printf("%-16s", VOLT_12_NAME);
status = naibrd_PS_GetVoltage( g_ps_cardIndex, NAI_PS_VOLT_MONITOR_12V, PS_MONITOR_MASK_ALL, 4, monitorVoltageArray );
if( status == NAI_SUCCESS)
{
print_ps_voltage(monitorVoltageArray ,'+');
}
status = naibrd_PS_GetCurrent( g_ps_cardIndex, NAI_PS_CURRENT_MONITOR_12V, PS_MONITOR_MASK_CURR_AVG_PEAK, 3, monitorCurrentArray );
if( status == NAI_SUCCESS)
{
print_ps_current(monitorCurrentArray);
}
print_ps_temperature_na();
printf("\n");
printf("%-16s", VOLT_MINUS_12_NAME);
status = naibrd_PS_GetVoltage( g_ps_cardIndex, NAI_PS_VOLT_MONITOR_MINUS_12V, PS_MONITOR_MASK_ALL, 4, monitorVoltageArray );
if( status == NAI_SUCCESS)
{
print_ps_voltage(monitorVoltageArray ,'-');
}
status = naibrd_PS_GetCurrent( g_ps_cardIndex, NAI_PS_CURRENT_MONITOR_MINUS_12V, PS_MONITOR_MASK_CURR_AVG_PEAK, 3, monitorCurrentArray );
if( status == NAI_SUCCESS)
{
print_ps_current(monitorCurrentArray);
}
print_ps_temperature_na();
printf("\n");
if ( status == NAI_SUCCESS )
{
print_ps_long_horizontal_border();
}
printf("\n");
return status;
}