nxdrvlinux/examples/api/cifxlinuxsample.c

988 lines
36 KiB
C
Raw Normal View History

// SPDX-License-Identifier: MIT
/**************************************************************************************
*
* Copyright (c) 2024, Hilscher Gesellschaft fuer Systemautomation mbH. All Rights Reserved.
*
* Description: cifX driver API demo application
*
* Changes:
*
* Version Date Author Description
* ----------------------------------------------------------------------------------
* 1 02.01.24 SD changed licensing terms
*
**************************************************************************************/
#include "cifxlinux.h"
#include "cifXEndianess.h"
#include "Hil_Packet.h"
#include "Hil_SystemCmd.h"
#include <errno.h>
#include <fcntl.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <termios.h>
#include <unistd.h>
#include <sys/mman.h>
#include <time.h>
#define CIFX_DEV "cifX0"
#ifndef UNREFERENCED_PARAMETER
#define UNREFERENCED_PARAMETER(a) (a=a)
#endif
typedef struct SYNC_CALLBACK_DATAtag
{
uint8_t bSyncHSMode;
CIFXHANDLE hDevice;
} SYNC_CALLBACK_DATA;
/*****************************************************************************/
/*! Callback rountine for events
* \param ulNotification Sync command
* \param ulDataLen Length of buffer referenced by pvData
* \param pvData Data
* \param pvUser User pointer */
/*****************************************************************************/
void APIENTRY EventCallback (uint32_t ulNotification, uint32_t ulDataLen, void* pvData, void* pvUser)
{
UNREFERENCED_PARAMETER(pvData);
UNREFERENCED_PARAMETER(ulDataLen);
switch (ulNotification)
{
case CIFX_NOTIFY_RX_MBX_FULL:
printf("EventCallback(): CIFX_NOTIFY_RX_MBX_FULL\n");
break;
case CIFX_NOTIFY_TX_MBX_EMPTY:
printf("EventCallback(): CIFX_NOTIFY_TX_MBX_EMPTY\n");
break;
case CIFX_NOTIFY_PD0_IN:
printf("EventCallback(): CIFX_NOTIFY_PD0_IN\n");
break;
case CIFX_NOTIFY_PD0_OUT:
printf("EventCallback(): CIFX_NOTIFY_PD0_OUT\n");
break;
case CIFX_NOTIFY_PD1_IN:
printf("EventCallback(): CIFX_NOTIFY_PD1_IN\n");
break;
case CIFX_NOTIFY_PD1_OUT:
printf("EventCallback(): CIFX_NOTIFY_PD1_OUT\n");
break;
default:
printf("EventCallback(): UNKNOWN Event, Event number %lu, pvUser 0x%08lx \n", (long unsigned int)ulNotification, (unsigned long)pvUser);
break;
}
}
/*****************************************************************************/
/*! Callback rountine for sync events
* \param ulNotification Sync command
* \param ulDataLen Length of buffer referenced by pvData
* \param pvData Data
* \param pvUser User pointer */
/*****************************************************************************/
void APIENTRY SyncEventCallback (uint32_t ulNotification, uint32_t ulDataLen, void* pvData, void* pvUser)
{
int32_t lRet = 0;
uint32_t ulErrorCount = 0;
SYNC_CALLBACK_DATA* ptSynchData = (SYNC_CALLBACK_DATA*)pvUser;
UNREFERENCED_PARAMETER(pvData);
UNREFERENCED_PARAMETER(ulDataLen);
UNREFERENCED_PARAMETER(ulNotification);
switch (ptSynchData->bSyncHSMode) {
case HIL_SYNC_MODE_DEV_CTRL:
printf("EventCallback(): Sync event - acknowledge requested (device controlled)\n");
lRet = xChannelSyncState( ptSynchData->hDevice, CIFX_SYNC_ACKNOWLEDGE_CMD, 1000, &ulErrorCount);
if(CIFX_NO_ERROR != lRet) {
printf("Error signaling the Sync, lRet = 0x%08X\n", (unsigned int)lRet);
}
break;
case HIL_SYNC_MODE_HST_CTRL:
printf("EventCallback(): Sync event (host controlled)\n");
/* dont do anything */
break;
default:
printf("EventCallback(): Error sync mode not known (mode=0x%X)!\n", ptSynchData->bSyncHSMode);
break;
}
}
static int kbhit()
{
struct termios oldt, newt;
int ch;
int oldf;
int iRet = 0;
tcgetattr(STDIN_FILENO, &oldt);
newt = oldt;
newt.c_lflag &= ~(ICANON | ECHO);
tcsetattr(STDIN_FILENO, TCSANOW, &newt);
oldf = fcntl(STDIN_FILENO, F_GETFL, 0);
fcntl(STDIN_FILENO, F_SETFL, oldf | O_NONBLOCK);
ch = getchar();
tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
fcntl(STDIN_FILENO, F_SETFL, oldf);
if(ch != EOF)
{
ungetc(ch, stdin);
iRet = 1;
}
return iRet;
}
/*****************************************************************************/
/*! Displays cifX error
* \param lError Error code */
/*****************************************************************************/
void ShowError( int32_t lError )
{
if( lError != CIFX_NO_ERROR)
{
char szError[1024] ={0};
xDriverGetErrorDescription( lError, szError, sizeof(szError));
printf("Error: 0x%X, <%s>\n", (unsigned int)lError, szError);
}
}
/*****************************************************************************/
/*! Displays a hex dump on the debug console (16 bytes per line)
* \param pbData Pointer to dump data
* \param ulDataLen Length of data dump */
/*****************************************************************************/
void DumpData(unsigned char* pbData, unsigned long ulDataLen)
{
unsigned long ulIdx;
#ifdef DEBUG
printf("%s() called\n", __FUNCTION__);
#endif
for(ulIdx = 0; ulIdx < ulDataLen; ++ulIdx)
{
if(0 == (ulIdx % 16))
printf("\r\n");
printf("%02X ", pbData[ulIdx]);
}
printf("\r\n");
}
/*****************************************************************************/
/*! Dumps a rcX packet to debug console
* \param ptPacket Pointer to packed being dumped */
/*****************************************************************************/
void DumpPacket(CIFX_PACKET* ptPacket)
{
#ifdef DEBUG
printf("%s() called\n", __FUNCTION__);
#endif
printf("Dest : 0x%08lX ID : 0x%08lX\r\n",(long unsigned int)HOST_TO_LE32(ptPacket->tHeader.ulDest), (long unsigned int)HOST_TO_LE32(ptPacket->tHeader.ulId));
printf("Src : 0x%08lX Sta : 0x%08lX\r\n",(long unsigned int)HOST_TO_LE32(ptPacket->tHeader.ulSrc), (long unsigned int)HOST_TO_LE32(ptPacket->tHeader.ulState));
printf("DestID : 0x%08lX Cmd : 0x%08lX\r\n",(long unsigned int)HOST_TO_LE32(ptPacket->tHeader.ulDestId),(long unsigned int)HOST_TO_LE32(ptPacket->tHeader.ulCmd));
printf("SrcID : 0x%08lX Ext : 0x%08lX\r\n",(long unsigned int)HOST_TO_LE32(ptPacket->tHeader.ulSrcId), (long unsigned int)HOST_TO_LE32(ptPacket->tHeader.ulExt));
printf("Len : 0x%08lX Rout : 0x%08lX\r\n",(long unsigned int)HOST_TO_LE32(ptPacket->tHeader.ulLen), (long unsigned int)HOST_TO_LE32(ptPacket->tHeader.ulRout));
printf("Data:");
DumpData(ptPacket->abData, HOST_TO_LE32(ptPacket->tHeader.ulLen));
}
/*****************************************************************************/
/*! Function to display driver information
* \param hDriver Handle to cifX driver
* \param ptVTable Pointer to cifX API function table
* \return CIFX_NO_ERROR on success */
/*****************************************************************************/
void DisplayDriverInformation (void)
{
int32_t lRet = CIFX_NO_ERROR;
DRIVER_INFORMATION tDriverInfo = {{0}};
char szDrvVersion[32] = "";
CIFXHANDLE hDriver = NULL;
if (CIFX_NO_ERROR == (lRet = xDriverOpen(&hDriver)))
{
printf("\n---------- Display Driver Version ----------\n");
if( CIFX_NO_ERROR != (lRet = xDriverGetInformation(hDriver, sizeof(tDriverInfo), &tDriverInfo)) )
ShowError( lRet);
else if ( CIFX_NO_ERROR != (lRet = cifXGetDriverVersion( sizeof(szDrvVersion)/sizeof(*szDrvVersion), szDrvVersion)))
ShowError( lRet);
else
printf("Driver Version: %s, based on %.32s \n\n", szDrvVersion, tDriverInfo.abDriverVersion);
/* close previously opened driver */
xDriverClose(hDriver);
}
printf(" State = 0x%08X\r\n", (unsigned int)lRet);
printf("----------------------------------------------------\r\n");
}
/*****************************************************************************/
/*! Function to demonstrate the board/channel enumeration
* \return CIFX_NO_ERROR on success */
/*****************************************************************************/
int32_t EnumBoardDemo(void)
{
#ifdef DEBUG
printf("%s() called\n", __FUNCTION__);
#endif
CIFXHANDLE hDriver = NULL;
int32_t lRet = xDriverOpen(&hDriver);
printf("---------- Board/Channel enumeration demo ----------\r\n");
if(CIFX_NO_ERROR == lRet)
{
/* Driver/Toolkit successfully opened */
unsigned long ulBoard = 0;
BOARD_INFORMATION tBoardInfo = {0};
/* Iterate over all boards */
while(CIFX_NO_ERROR == xDriverEnumBoards(hDriver, ulBoard, sizeof(tBoardInfo), &tBoardInfo))
{
printf("Found Board %s\r\n", tBoardInfo.abBoardName);
if(strlen( (char*)tBoardInfo.abBoardAlias) != 0)
printf(" Alias : %s\r\n", tBoardInfo.abBoardAlias);
printf(" DeviceNumber : %lu\r\n",(long unsigned int)tBoardInfo.tSystemInfo.ulDeviceNumber);
printf(" SerialNumber : %lu\r\n",(long unsigned int)tBoardInfo.tSystemInfo.ulSerialNumber);
printf(" Board ID : %lu\r\n",(long unsigned int)tBoardInfo.ulBoardID);
printf(" System Error : 0x%08lX\r\n",(long unsigned int)tBoardInfo.ulSystemError);
printf(" Channels : %lu\r\n",(long unsigned int)tBoardInfo.ulChannelCnt);
printf(" DPM Size : %lu\r\n",(long unsigned int)tBoardInfo.ulDpmTotalSize);
unsigned long ulChannel = 0;
CHANNEL_INFORMATION tChannelInfo = {{0}};
/* iterate over all channels on the current board */
while(CIFX_NO_ERROR == xDriverEnumChannels(hDriver, ulBoard, ulChannel, sizeof(tChannelInfo), &tChannelInfo))
{
printf(" - Channel %lu:\r\n", ulChannel);
printf(" Firmware : %s\r\n", tChannelInfo.abFWName);
printf(" Version : %u.%u.%u build %u\r\n",
tChannelInfo.usFWMajor,
tChannelInfo.usFWMinor,
tChannelInfo.usFWRevision,
tChannelInfo.usFWBuild);
printf(" Date : %02u/%02u/%04u\r\n",
tChannelInfo.bFWMonth,
tChannelInfo.bFWDay,
tChannelInfo.usFWYear);
printf(" Device Nr. : %lu\r\n",(long unsigned int)tChannelInfo.ulDeviceNumber);
printf(" Serial Nr. : %lu\r\n",(long unsigned int)tChannelInfo.ulSerialNumber);
printf(" netX Flags : 0x%08X\r\n", tChannelInfo.ulNetxFlags);
printf(" Host Flags : 0x%08X\r\n", tChannelInfo.ulHostFlags);
printf(" Host COS : 0x%08X\r\n", tChannelInfo.ulHostCOSFlags);
printf(" Device COS : 0x%08X\r\n", tChannelInfo.ulDeviceCOSFlags);
++ulChannel;
}
++ulBoard;
}
/* close previously opened driver */
xDriverClose(hDriver);
}
printf(" State = 0x%08X\r\n", (unsigned int)lRet);
printf("----------------------------------------------------\r\n");
return lRet;
}
/*****************************************************************************/
/*! Function to demonstrate system channel functionality (PacketTransfer)
* \return CIFX_NO_ERROR on success */
/*****************************************************************************/
int32_t SysdeviceDemo()
{
#ifdef DEBUG
printf("%s() called\n", __FUNCTION__);
#endif
CIFXHANDLE hDriver = NULL;
int32_t lRet = xDriverOpen(&hDriver);
printf("---------- System Device handling demo ----------\r\n");
if(CIFX_NO_ERROR == lRet)
{
/* Driver/Toolkit successfully opened */
CIFXHANDLE hSys = NULL;
lRet = xSysdeviceOpen(hDriver, CIFX_DEV, &hSys);
if(CIFX_NO_ERROR != lRet)
{
printf("Error opening SystemDevice!\r\n");
} else
{
SYSTEM_CHANNEL_SYSTEM_INFO_BLOCK tSysInfoBlock = {{0}};
SYSTEM_CHANNEL_SYSTEM_INFORMATION tSysInfo = {0};
SYSTEM_CHANNEL_SYSTEM_CONTROL_BLOCK tControlBlock = {0};
SYSTEM_CHANNEL_SYSTEM_STATUS_BLOCK tStatusBlock = {0};
/* System channel successfully opened, try to read the System Info Block */
if( CIFX_NO_ERROR != (lRet = xSysdeviceInfo(hSys, CIFX_INFO_CMD_SYSTEM_INFO_BLOCK, sizeof(tSysInfoBlock), &tSysInfoBlock)))
{
printf("Error querying system information block\r\n");
} else
{
printf("System Channel Info Block:\r\n");
printf("==========================\r\n");
printf("DPM Cookie : %.4s\r\n",(char*)tSysInfoBlock.abCookie);
printf("DPM Size : %lu\r\n",(long unsigned int)tSysInfoBlock.ulDpmTotalSize);
printf("Device Number : %lu\r\n",(long unsigned int)tSysInfoBlock.ulDeviceNumber);
printf("Serial Number : %lu\r\n",(long unsigned int)tSysInfoBlock.ulSerialNumber);
printf("HW Options : 0x%04X 0x%04X 0x%04X 0x%04X\r\n",
tSysInfoBlock.ausHwOptions[0], tSysInfoBlock.ausHwOptions[1],
tSysInfoBlock.ausHwOptions[2], tSysInfoBlock.ausHwOptions[3]);
printf("Manufacturer : %u\r\n", tSysInfoBlock.usManufacturer);
printf("Production Date : %u\r\n", tSysInfoBlock.usProductionDate);
printf("Device Class : %u\r\n", tSysInfoBlock.usDeviceClass);
printf("HW Revision : %u\r\n", tSysInfoBlock.bHwRevision);
printf("HW Compatibility : %u\r\n", tSysInfoBlock.bHwCompatibility);
printf("License Flags 1 : 0x%08X\r\n", tSysInfoBlock.ulLicenseFlags1);
printf("License Flags 2 : 0x%08X\r\n", tSysInfoBlock.ulLicenseFlags2);
printf("LicenseID : 0x%04X\r\n", tSysInfoBlock.usNetxLicenseID);
printf("LicenseFlags : 0x%04X\r\n", tSysInfoBlock.usNetxLicenseFlags);
printf("==========================\r\n");
}
/* Try to read the System Information */
if( CIFX_NO_ERROR != (lRet = xSysdeviceInfo(hSys, CIFX_INFO_CMD_SYSTEM_INFORMATION, sizeof(tSysInfo), &tSysInfo)))
{
printf("Error querying system information\r\n");
} else
{
printf("System Information:\r\n");
printf("===================\r\n");
printf("System Error : 0x%08X\r\n", tSysInfo.ulSystemError);
printf("DPM Size : %lu\r\n", (long unsigned int)tSysInfo.ulDpmTotalSize);
printf("Mailbox size : %lu\r\n", (long unsigned int)tSysInfo.ulMBXSize);
printf("Device Number : %lu\r\n", (long unsigned int)tSysInfo.ulDeviceNumber);
printf("Serial Number : %lu\r\n", (long unsigned int)tSysInfo.ulSerialNumber);
printf("Open Count : %lu\r\n", (long unsigned int)tSysInfo.ulOpenCnt);
printf("===================\r\n");
}
/* Try to read the System Control Block */
if( CIFX_NO_ERROR != (lRet = xSysdeviceInfo(hSys, CIFX_INFO_CMD_SYSTEM_CONTROL_BLOCK, sizeof(tControlBlock), &tControlBlock)))
{
printf("Error querying system control block\r\n");
} else
{
printf("System Control Block:\r\n");
printf("=====================\r\n");
printf("Command COS : 0x%08X\r\n", tControlBlock.ulSystemCommandCOS);
printf("System Control : 0x%08X\r\n", tControlBlock.ulSystemControl);
printf("=====================\r\n");
}
printf("Waiting 2s to let cifX card calculate CPU load!\r\n");
sleep(2);
/* Try to read the System Status Block */
if( CIFX_NO_ERROR != (lRet = xSysdeviceInfo(hSys, CIFX_INFO_CMD_SYSTEM_STATUS_BLOCK, sizeof(tStatusBlock), &tStatusBlock)))
{
printf("Error querying system status block\r\n");
} else
{
printf("System Status Block:\r\n");
printf("====================\r\n");
printf("System COS : 0x%08X\r\n", tStatusBlock.ulSystemCOS);
printf("System Status : 0x%08X\r\n", tStatusBlock.ulSystemStatus);
printf("System Error : 0x%08X\r\n", tStatusBlock.ulSystemError);
printf("Time since start : %lu\r\n", (long unsigned int)tStatusBlock.ulTimeSinceStart);
printf("CPU Load [%%] : %.2f\r\n", (float)tStatusBlock.usCpuLoad / 100);
printf("====================\r\n");
}
unsigned long ulSendPktCount = 0;
unsigned long ulRecvPktCount = 0;
printf("\r\n");
printf("Trying to read Security Eeprom:\r\n");
printf("===============================\r\n");
/* Read Security EEPROM zone 1*/
xSysdeviceGetMBXState(hSys, (uint32_t*)&ulRecvPktCount, (uint32_t*)&ulSendPktCount);
printf("System Mailbox State: MaxSend = %lu, Pending Receive = %lu\r\n",
ulSendPktCount, ulRecvPktCount);
HIL_SECURITY_EEPROM_READ_REQ_T tCryptoRead = {{0}};
HIL_SECURITY_EEPROM_READ_CNF_T tCryptoReadCnf = {{0}};
tCryptoRead.tHead.ulDest = HOST_TO_LE32(HIL_PACKET_DEST_SYSTEM);
tCryptoRead.tHead.ulLen = HOST_TO_LE32(sizeof(tCryptoRead.tData));
tCryptoRead.tHead.ulCmd = HOST_TO_LE32(HIL_SECURITY_EEPROM_READ_REQ);
tCryptoRead.tData.ulZoneId = HOST_TO_LE32(1);
if(CIFX_NO_ERROR != (lRet = xSysdevicePutPacket(hSys, (CIFX_PACKET*)&tCryptoRead, 10)))
{
printf("Error sending packet to device (0x%X)!\r\n", lRet);
} else
{
printf("Send Packet (Read Crypto Flash Zone 1):\r\n");
DumpPacket((CIFX_PACKET*)&tCryptoRead);
xSysdeviceGetMBXState(hSys, (uint32_t*)&ulRecvPktCount, (uint32_t*)&ulSendPktCount);
printf("System Mailbox State: MaxSend = %lu, Pending Receive = %lu\r\n",
ulSendPktCount, ulRecvPktCount);
if(CIFX_NO_ERROR != (lRet = xSysdeviceGetPacket(hSys, sizeof(tCryptoReadCnf), (CIFX_PACKET*)&tCryptoReadCnf, 20)) )
{
printf("Error getting packet from device! (lRet=0x%08X)\r\n",(unsigned int)lRet);
} else
{
printf("Received Packet (Read Crypto Flash Zone 1):\r\n");
DumpPacket((CIFX_PACKET*)&tCryptoReadCnf);
xSysdeviceGetMBXState(hSys, (uint32_t*)&ulRecvPktCount, (uint32_t*)&ulSendPktCount);
printf("System Mailbox State: MaxSend = %lu, Pending Receive = %lu\r\n",
ulSendPktCount, ulRecvPktCount);
}
}
printf("===============================\r\n");
printf("\r\n");
xSysdeviceClose(hSys);
}
xDriverClose(hDriver);
}
printf(" State = 0x%08X\r\n", (unsigned int)lRet);
printf("----------------------------------------------------\r\n");
return lRet;
}
/*****************************************************************************/
/*! Function to demonstrate communication channel functionality
* Packet Transfer and I/O Data exchange
* \return CIFX_NO_ERROR on success */
/*****************************************************************************/
int32_t ChannelDemo()
{
#ifdef DEBUG
printf("%s() called\n", __FUNCTION__);
#endif
CIFXHANDLE hDriver = NULL;
int32_t lRet = xDriverOpen(&hDriver);
printf("---------- Communication Channel demo ----------\r\n");
if(CIFX_NO_ERROR == lRet)
{
/* Driver/Toolkit successfully opened */
CIFXHANDLE hChannel = NULL;
lRet = xChannelOpen(hDriver, CIFX_DEV, 0, &hChannel);
if(CIFX_NO_ERROR != lRet)
{
printf("Error opening Channel!");
} else
{
CHANNEL_INFORMATION tChannelInfo = {{0}};
/* Channel successfully opened, so query basic information */
if( CIFX_NO_ERROR != (lRet = xChannelInfo(hChannel, sizeof(CHANNEL_INFORMATION), &tChannelInfo)))
{
printf("Error querying system information block\r\n");
} else
{
printf("Communication Channel Info:\r\n");
printf("Device Number : %lu\r\n",(long unsigned int)tChannelInfo.ulDeviceNumber);
printf("Serial Number : %lu\r\n",(long unsigned int)tChannelInfo.ulSerialNumber);
printf("Firmware : %s\r\n", tChannelInfo.abFWName);
printf("FW Version : %u.%u.%u build %u\r\n",
tChannelInfo.usFWMajor,
tChannelInfo.usFWMinor,
tChannelInfo.usFWRevision,
tChannelInfo.usFWBuild);
printf("FW Date : %02u/%02u/%04u\r\n",
tChannelInfo.bFWMonth,
tChannelInfo.bFWDay,
tChannelInfo.usFWYear);
printf("Mailbox Size : %lu\r\n",(long unsigned int)tChannelInfo.ulMailboxSize);
}
uint32_t ulSendPktCount = 0;
uint32_t ulRecvPktCount = 0;
CIFX_PACKET tSendPkt = {{0}};
CIFX_PACKET tRecvPkt = {{0}};
printf("\nStart put/get packet Demo!\n");
/* Read Security EEPROM zone 1*/
xChannelGetMBXState( hChannel, (uint32_t*)&ulRecvPktCount, (uint32_t*)&ulSendPktCount);
printf("Channel Mailbox State: MaxSend = %u, Pending Receive = %u\r\n",
ulSendPktCount, ulRecvPktCount);
/* Do a basic Packet Transfer */
if(CIFX_NO_ERROR != (lRet = xChannelPutPacket(hChannel, &tSendPkt, 10)))
{
printf("Error sending packet to device (0x%X)!\r\n", lRet);
} else
{
printf("Send Packet:\r\n");
DumpPacket(&tSendPkt);
if(CIFX_NO_ERROR != (lRet = xChannelGetPacket(hChannel, sizeof(tRecvPkt), &tRecvPkt, 20)) )
{
printf("Error getting packet from device!\r\n");
} else
{
printf("Received Packet:\r\n");
DumpPacket(&tRecvPkt);
}
}
sleep(1);
printf("\nStart read/write IO-Data!\n");
/* Read and write I/O data (32Bytes). Output data will be incremented each cyle */
unsigned char abSendData[32] = {0};
unsigned char abRecvData[32] = {0};
unsigned long ulCycles = 0;
unsigned long ulState;
if(CIFX_NO_ERROR != (lRet = xChannelBusState(hChannel, CIFX_BUS_STATE_ON,(uint32_t*) &ulState, 10000)))
{
printf("Error setting Bus state lRet = 0x%08X!\r\n",(unsigned int)lRet);
xChannelClose(hChannel);
xDriverClose(hDriver);
return lRet;
}
printf("IO Demo running <Hit any key to abort>:\n");
while(!kbhit())
{
++ulCycles;
usleep(1 * 1000); /* Wait 1 ms so we can see the counter on the LEDs */
if(CIFX_NO_ERROR != (lRet = xChannelIORead(hChannel, 0, 0, sizeof(abRecvData), abRecvData, 10)))
{
printf("Error reading IO Data area!\r\n");
break;
} else
{
#ifdef DEBUG
printf("IORead Data:");
DumpData(abRecvData, sizeof(abRecvData));
#endif
memcpy(abSendData, abRecvData, sizeof(abRecvData));
/* On a CB-AB32 we will echo the input 8 buttons if one is pressed, otherwise a counter
will be placed on output */
if(abRecvData[0] == 0)
abSendData[0] = (unsigned char)ulCycles;
if(CIFX_NO_ERROR != (lRet = xChannelIOWrite(hChannel, 0, 0, sizeof(abSendData), abSendData, 10)))
{
printf("Error writing to IO Data area!\r\n");
break;
} else
{
#ifdef DEBUG
printf("IOWrite Data:");
DumpData(abSendData, sizeof(abSendData));
#endif
}
}
}
printf("IODemo ended. Total cycles %lu\n", ulCycles);
if(CIFX_NO_ERROR != (lRet = xChannelBusState(hChannel, CIFX_BUS_STATE_OFF, (uint32_t*)&ulState, 10000)))
{
printf("Error setting Bus state lRet = 0x%08X!\r\n",(unsigned int)lRet);
}
xChannelClose(hChannel);
}
xDriverClose(hDriver);
}
printf(" State = 0x%08X\r\n", (unsigned int)lRet);
printf("----------------------------------------------------\r\n");
return lRet;
}
/*****************************************************************************/
/*! Function to demonstrate control/status block functionality
* \return CIFX_NO_ERROR on success */
/*****************************************************************************/
int32_t BlockDemo( void)
{
CIFXHANDLE hDriver = NULL;
int32_t lRet = xDriverOpen(&hDriver);
#ifdef DEBUG
printf("%s() called\n", __FUNCTION__);
#endif
printf("\n--- Read / Write Block Information ---\r\n");
/* Open channel */
if(CIFX_NO_ERROR == lRet)
{
CIFXHANDLE hDevice = NULL;
lRet = xChannelOpen(hDriver, CIFX_DEV, 0, &hDevice);
if(lRet != CIFX_NO_ERROR)
{
printf("Error opening Channel!\r\n");
} else
{
unsigned char abBuffer[4] = {0};
/* Read / Write control block */
printf("Read CONTROL Block \r\n");
memset( abBuffer, 0, sizeof(abBuffer));
lRet = xChannelControlBlock( hDevice, CIFX_CMD_READ_DATA, 0, 4, &abBuffer[0]);
DumpData(abBuffer, 4);
printf("Write CONTROL Block \r\n");
lRet = xChannelControlBlock( hDevice, CIFX_CMD_WRITE_DATA, 0, 4, &abBuffer[0]);
printf("Read COMMON Status Block \r\n");
memset( abBuffer, 0, sizeof(abBuffer));
lRet = xChannelCommonStatusBlock( hDevice, CIFX_CMD_READ_DATA, 0, 4, &abBuffer[0]);
DumpData(abBuffer, 4);
printf("Write COMMON Status Block \r\n");
lRet = xChannelCommonStatusBlock( hDevice, CIFX_CMD_WRITE_DATA, 0, 4, &abBuffer[0]);
/* this is expected to fail, as this block must not be written by Host */
if(CIFX_NO_ERROR != lRet)
printf("Error writing to common status block. lRet = 0x%08X\r\n", (unsigned int)lRet);
printf("Read EXTENDED Status Block \r\n");
memset( abBuffer, 0, sizeof(abBuffer));
lRet = xChannelExtendedStatusBlock( hDevice, CIFX_CMD_READ_DATA, 0, 4, &abBuffer[0]);
DumpData(abBuffer, 4);
printf("Write EXTENDED Status Block \r\n");
lRet = xChannelExtendedStatusBlock( hDevice, CIFX_CMD_WRITE_DATA, 0, 4, &abBuffer[0]);
/* this is expected to fail, as this block must not be written by Host */
if(CIFX_NO_ERROR != lRet)
printf("Error writing to extended status block. lRet = 0x%08X\r\n", (unsigned int)lRet);
xChannelClose(hDevice);
}
xDriverClose(hDriver);
}
return lRet;
}
/*****************************************************************************/
/*! Function to demonstrate bus / host state
* \return CIFX_NO_ERROR on success */
/*****************************************************************************/
int32_t StateDemo (void)
{
CIFXHANDLE hDriver = NULL;
CIFXHANDLE hChannel = NULL;
int32_t lRet = xDriverOpen(&hDriver);
printf("\n--- Set Bus / Host State Demo ---\n");
if (CIFX_NO_ERROR == lRet)
{
/* Open channel */
if( CIFX_NO_ERROR != (lRet = xChannelOpen(hDriver, CIFX_DEV, 0, &hChannel)))
{
printf("Error opening Channel!\n");
} else
{
uint32_t ulState = 0;
/* Set Host ready */
lRet = xChannelHostState( hChannel, CIFX_HOST_STATE_READY, &ulState, 1000);
if (CIFX_NO_ERROR != lRet)
printf("Error CIFX_HOST_STATE_READY, state %lu, error 0x%08X !\n", (long unsigned int)ulState, (unsigned int)lRet);
else
printf("Set CIFX_HOST_STATE_READY!\n");
/* Get Host state */
lRet = xChannelHostState( hChannel, CIFX_HOST_STATE_READ, &ulState, 1000);
if (CIFX_NO_ERROR != lRet)
printf("Error CIFX_HOST_STATE_READ, state %lu, error 0x%08X !\n", (long unsigned int)ulState, (unsigned int)lRet);
else
printf("CIFX_HOST_STATE_READ, state %lu !\n", (long unsigned int)ulState);
/* Set Bus state on */
lRet = xChannelBusState (hChannel, CIFX_BUS_STATE_ON, &ulState, 1000);
if (CIFX_NO_ERROR != lRet)
printf("Error CIFX_BUS_STATE_ON, state %lu, error 0x%08X !\n", (long unsigned int)ulState, (unsigned int)lRet);
else
printf("CIFX_BUS_STATE_ON, state %lul !\n", (long unsigned int)ulState);
/* Set Bus state off */
lRet = xChannelBusState (hChannel, CIFX_BUS_STATE_OFF, &ulState, 1000);
if (CIFX_NO_ERROR != lRet)
printf("Error CIFX_BUS_STATE_OFF, state %lu, error 0x%08X !\n", (long unsigned int)ulState, (unsigned int)lRet);
else
printf("CIFX_BUS_STATE_OFF, state %lu !\n", (long unsigned int)ulState);
/* Set Host not ready */
lRet = xChannelHostState(hChannel, CIFX_HOST_STATE_NOT_READY, &ulState, 1000);
if (CIFX_NO_ERROR != lRet)
printf("Error CIFX_HOST_STATE_NOT_READY, state %lu, error 0x%08X !\n", (long unsigned int)ulState,(unsigned int)lRet);
else
printf("Set CIFX_HOST_STATE_NOT_READY!\n");
/* Get Host state */
lRet = xChannelHostState( hChannel, CIFX_HOST_STATE_READ, &ulState, 1000);
if (CIFX_NO_ERROR != lRet)
printf("Error CIFX_HOST_STATE_READ, state %lu, error 0x%08X !\n", (long unsigned int)ulState, (unsigned int)lRet);
else
printf("CIFX_HOST_STATE_READ, state %lu !\n", (long unsigned int)ulState);
xChannelClose(hChannel);
}
xDriverClose(hDriver);
}
printf(" State = 0x%08X\n", (unsigned int)lRet);
printf("----------------------------------------------------\n");
return lRet;
}
/*****************************************************************************/
/*! Function to demonstrate event handling
* \return CIFX_NO_ERROR on success */
/*****************************************************************************/
void TestEventHandling(void)
{
CIFXHANDLE hDriver = NULL;
CIFXHANDLE hDevice = NULL;
int32_t lRet = xDriverOpen(&hDriver);
int iIdx = 0;
printf("\n--- Event handling demo ---\r\n");
/* Open channel */
if (CIFX_NO_ERROR == lRet)
{
lRet = xChannelOpen(hDriver, CIFX_DEV, 0, &hDevice);
if(lRet != CIFX_NO_ERROR)
{
/* Read driver error description */
ShowError( lRet);
} else
{
uint32_t ulState = 0;
SYNC_CALLBACK_DATA tSynchData = {0};
HIL_DPM_COMMON_STATUS_BLOCK_T tCommonState = {0};
int32_t fSync = 0;
lRet = xChannelCommonStatusBlock( hDevice, CIFX_CMD_READ_DATA, 0, sizeof(tCommonState), &tCommonState);
if ( (CIFX_NO_ERROR == lRet) || (CIFX_DEV_NOT_RUNNING == lRet)) {
/* xChannelCommonStatusBlock() return value is also state information, therefore CIFX_DEV_NOT_RUNNING is also valid */
tSynchData.bSyncHSMode = tCommonState.bSyncHskMode;
printf("Sync-handshake mode: 0x%.2x ", tSynchData.bSyncHSMode);
if (tSynchData.bSyncHSMode == HIL_SYNC_MODE_DEV_CTRL) {
printf("(device controlled)\n\n");
} else if (tSynchData.bSyncHSMode == HIL_SYNC_MODE_HST_CTRL) {
printf("(host controlled)\n\n");
} else {
fSync = 0;
printf("(mode unknown!!!)\n");
printf("Failed to determine sync-handshake mode. Skip sync notification.\n\n");
}
} else {
fSync = 0;
printf("Failed to determine sync-handshake mode (0x%X). Skip sync notification.\n\n", lRet);
}
tSynchData.hDevice = hDevice;
/* Register for events */
if( (CIFX_NO_ERROR != (lRet = xChannelRegisterNotification( hDevice, CIFX_NOTIFY_RX_MBX_FULL, EventCallback, (void*)1))) ||
(CIFX_NO_ERROR != (lRet = xChannelRegisterNotification( hDevice, CIFX_NOTIFY_TX_MBX_EMPTY, EventCallback, (void*)2))) ||
(CIFX_NO_ERROR != (lRet = xChannelRegisterNotification( hDevice, CIFX_NOTIFY_PD0_IN, EventCallback, (void*)3))) ||
(CIFX_NO_ERROR != (lRet = xChannelRegisterNotification( hDevice, CIFX_NOTIFY_PD0_OUT, EventCallback, (void*)5))) ||
((fSync == 1) && (CIFX_NO_ERROR != (lRet = xChannelRegisterNotification( hDevice, CIFX_NOTIFY_SYNC, SyncEventCallback, (void*)&tSynchData)))) )
{
/* Failed to register one of the events */
/* Read driver error description */
ShowError( lRet);
} else
{
/* Get actual host state */
if( (lRet = xChannelHostState( hDevice, CIFX_HOST_STATE_READ, &ulState, 0L)) != CIFX_NO_ERROR)
{
/* Read driver error description */
ShowError( lRet);
}
/* Set host ready */
if( (lRet = xChannelHostState( hDevice, CIFX_HOST_STATE_READY, NULL, 2000L)) != CIFX_NO_ERROR)
{
/* Read driver error description */
ShowError( lRet);
}
for (iIdx=0; iIdx<10; iIdx++)
{
uint32_t ulRecvPktCount = 0;
uint32_t ulSendPktCount = 0;
CIFX_PACKET tSendPkt = {{0}};
xChannelGetMBXState( hDevice, (uint32_t*)&ulRecvPktCount, (uint32_t*)&ulSendPktCount);
if (ulSendPktCount > 0)
xChannelPutPacket(hDevice, &tSendPkt, 10);
xChannelIORead(hDevice, 0, 0, sizeof(tSendPkt), &tSendPkt, 10);
xChannelIOWrite(hDevice, 0, 0, sizeof(tSendPkt), &tSendPkt, 10);
xChannelGetMBXState( hDevice, (uint32_t*)&ulRecvPktCount, (uint32_t*)&ulSendPktCount);
if (ulRecvPktCount > 0) {
xChannelGetPacket( hDevice, sizeof(tSendPkt), &tSendPkt, 100);
}
}
if (fSync == 1) {
sleep(1);
}
/*-------------------*/
/* Unregister Events */
/*-------------------*/
lRet = xChannelUnregisterNotification( hDevice, CIFX_NOTIFY_RX_MBX_FULL);
if( CIFX_NO_ERROR != lRet)
printf("Error in Unregister CIFX_NOTIFY_RX_MBX_FULL event, Error = 0x%08X", (unsigned int)lRet);
lRet = xChannelUnregisterNotification( hDevice, CIFX_NOTIFY_TX_MBX_EMPTY);
if( CIFX_NO_ERROR != lRet)
printf("Error in Unregister CIFX_NOTIFY_TX_MBX_EMPTY event, Error = 0x%08X", (unsigned int)lRet);
lRet = xChannelUnregisterNotification( hDevice, CIFX_NOTIFY_PD0_IN);
if( CIFX_NO_ERROR != lRet)
printf("Error in Unregister CIFX_NOTIFY_PD0_IN event, Error = 0x%08X", (unsigned int)lRet);
lRet = xChannelUnregisterNotification( hDevice, CIFX_NOTIFY_PD0_OUT);
if( CIFX_NO_ERROR != lRet)
printf("Error in Unregister CIFX_NOTIFY_PD0_OUT event, Error = 0x%08X", (unsigned int)lRet);
if (fSync == 1) {
lRet = xChannelUnregisterNotification( hDevice, CIFX_NOTIFY_SYNC);
if( CIFX_NO_ERROR != lRet)
printf("Error in Unregister CIFX_NOTIFY_SYNC event, Error = 0x%08X", (unsigned int)lRet);
}
}
/* Close channel */
if( hDevice != NULL)
xChannelClose(hDevice);
}
xDriverClose(hDriver);
}
}
/*****************************************************************************/
/*! Main entry function
* \return 0 */
/*****************************************************************************/
int main(int argc, char* argv[])
{
struct CIFX_LINUX_INIT init =
{
.init_options = CIFX_DRIVER_INIT_AUTOSCAN,
.iCardNumber = 0,
.fEnableCardLocking = 0,
.base_dir = NULL,
.poll_interval = 0,
.poll_StackSize = 0, /* set to 0 to use default */
.trace_level = 255,
.user_card_cnt = 0,
.user_cards = NULL,
};
#ifdef DEBUG
printf("%s() called\n", __FUNCTION__);
#endif
/* First of all initialize toolkit */
int32_t lRet = cifXDriverInit(&init);
if(CIFX_NO_ERROR == lRet)
{
/* Display version of cifXRTXDrv and cifXToolkit */
DisplayDriverInformation();
/* Demonstrate the board/channel enumeration */
EnumBoardDemo();
/* Demonstrate system channel functionality */
SysdeviceDemo();
/* Demonstrate communication channel functionality */
ChannelDemo();
/* Demonstrate control/status block functionality */
BlockDemo();
/* Demonstrate event handling */
TestEventHandling();
/* Demonstrate host/bus state functions */
StateDemo ();
}
cifXDriverDeinit();
return 0;
}