cifX PCI Information
1. Hilscher PCI Vendor and Device IDs
Attention:
The SUBSYSTEM_ID isused to determine if the hardware is:
"RAM based" = Firmware and configuration is not stored on the hardware
"FLASH based" = Firmware and configuration is stored on the hardware
Depending on the functionality the start-up behaviour of the hardware is
different!
Hilscher PCI/PCIe Hardware information (CIFX50 / CIFX70 / CIFX90 etc.)
VENDOR_ID => 0x15CF /* Hilscher GmbH */
DEVICE_ID => 0x0000
SUBVENDOR_ID => 0x0000
SUBSYSTEM_ID => 0x0000
Hilscher netPLC ("RAM based" / "FLASH based"):
VENDOR_ID => 0x15CF /* Hilscher GmbH */
DEVICE_ID => 0x0010
SUBVENDOR_ID => 0x15CF
SUBSYSTEM_ID => 0x0000 /* RAM based device */
SUBSYSTEM_ID => 0x0001 /* FLASH based device */
Hilscher netJACK ("RAM based" / "FLASH based"):
VENDOR_ID => 0x15CF /* Hilscher GmbH */
DEVICE_ID => 0x0020
SUBVENDOR_ID => 0x15CF
SUBSYSTEM_ID => 0x0000 /* RAM based device */
SUBSYSTEM_ID => 0x0001 /* FLASH based device */
2. Hilscher CIFX device -> PCI-Register-Information:
BAR 0 = DPM_BASE_ADDRESS => Dual Ported Memory CIFX
BAR 1 = TARGET_BASE_ADDRESS => MRAM Area if suporrted by hardware
BAR 2 = I/O_BASE_ADDRESS => Special netX feature currently unused
BAR 3 = unused
BAR 4 = unused
BAR 5 = unused
2.1 Hilscher CIFX device -> Calculate the DPM size:
The size of the DPM can be calculated form the BASE ADDRESS REGISTER (BAR).
This is a "standard" functionality from PCI and described in the
PCI specification.
1) save the current BAR content (this is the physical memory address)
2) write all ones to the BAR register
3) read the BAR value back (Memory Information)
4) restore the BAR with the previous saved value (physical memory address)
5) compute the size from the "Memory Information" value
This iis done by masking out the lowest 4 bit (for a memory BAR) and
building the 2 complement of the value (invert the value and add 1).
if (val & 1)
size = (~val | 0x3) + 1; /* I/O space */
else
size = (~val | 0xF) + 1; /* memory space */
The resulting value is the memory size in bytes.
3. Hilscher CIFX device -> PCI Interrupt Enable:
Interrupt enable is only possible via the so called netX Global-Register block located at the end of the netX DPM (Dual Ported Memory last 512 Byte = 0x200).
All definitions for the netX "Global-Register Block can be found in the file: NetX_RegDefs.h
This file is inculded in the cifX/netX Toolkit sources.
3.1 Information from NetX_RegDefs.h
#define NETX_DPM_MEMORY_SIZE 0x10000
/* DPMHS_INT_EN0 Bits [31:29] */
#define MSK_IRQ_EN0_INT_REQ 0x80000000 /*!< Global Interrupt bitmask */
#define SRT_IRQ_EN0_INT_REQ 31 /*!< Shift right term for global interrupt */
/* DPMHS_INT_EN0 Bits [15:0] */
#define MSK_IRQ_EN0_HANDSHAKE 0x0000FFFF /*!< Handshake interrupt mask (Each bit = 1 cell) */
#define SRT_IRQ_EN0_HANDSHAKE 0 /*!< Shift right term for handshake interrupt */
/*****************************************************************************/
/*! netX Host Register Block, always located at Offset DPMSize - 0x200 */
/*****************************************************************************/
typedef struct NETX_GLOBAL_REG_BLOCKtag
{
/* 0xFE00, start of the DMA channel data (8Channels * 8DWords * 4Bytes/DWord = 0x100 Bytes) */
NETX_DMA_CHANNEL_CONFIG atDmaCtrl[NETX_MAX_DMA_CHANNELS]; /*!< Configuration Register for all 8 DMA Channels */
/* 0xFF00, start of the netX Host control block */
volatile uint32_t reserved[47]; /*!< unused/reserved */
/* 0xFFBC, start of the defined registers */
volatile uint32_t ulPCIBaseAddress; /*!< PCI Base address of 2nd Memory Window */
volatile uint32_t ulWatchDogTimeoutHost; /*!< Host Watchdog Timeout value */
volatile uint32_t ulWatchDogTrigger; /*!< Host Watchdog triggering cell */
volatile uint32_t ulWatchDogTimeoutNetx; /*!< NetX Watchdog Timeout value */
volatile uint32_t reserved2; /*!< unused/reserved */
volatile uint32_t ulCyclicTimerControl; /*!< Control of cyclic timer (repeat/single,
timer resolution, up/down) */
volatile uint32_t ulCyclicTimerStart; /*!< Timer start value */
volatile uint32_t ulSystemState; /*!< System state register */
volatile uint32_t ulHostReset; /*!< Host reset for initiating a hard reset of
the netX chip */
volatile uint32_t ulIRQState_0; /*!< IRQ State 0 */
volatile uint32_t ulIRQState_1; /*!< IRQ State 1 */
volatile uint32_t reserved3; /*!< unused/reserved */
volatile uint32_t reserved4; /*!< unused/reserved */
volatile uint32_t ulIRQEnable_0; /*!< IRQ enable register 0 */
volatile uint32_t ulIRQEnable_1; /*!< IRQ enable register 1 */
volatile uint32_t reserved5; /*!< unused/reserved */
volatile uint32_t reserved6; /*!< unused/reserved */
} NETX_GLOBAL_REG_BLOCK,*PNETX_GLOBAL_REG_BLOCK;
3.2 Example from the cifX/netX Toolkit
/*****************************************************************************/
/*! Physically Enable Interrupts on hardware
* \param ptDevInstance Device instance */
/*****************************************************************************/
void cifXTKitEnableHWInterrupt(PDEVICEINSTANCE ptDevInstance)
{
/* Set interrupt enable bits in PCI mode only if the complete 64KByte DPM is available */
if( (ptDevInstance->fPCICard) ||
(ptDevInstance->ulDPMSize >= NETX_DPM_MEMORY_SIZE) )
{
/* Enable global and handshake interrupts */
HWIF_WRITE32(ptDevInstance, ptDevInstance->ptGlobalRegisters->ulIRQEnable_0,
HOST_TO_LE32((MSK_IRQ_EN0_INT_REQ | MSK_IRQ_EN0_HANDSHAKE) ));
HWIF_WRITE32(ptDevInstance, ptDevInstance->ptGlobalRegisters->ulIRQEnable_1, 0);
}
}
/*****************************************************************************/
/*! Physically Disable Interrupts on hardware
* \param ptDevInstance Device instance */
/*****************************************************************************/
void cifXTKitDisableHWInterrupt(PDEVICEINSTANCE ptDevInstance)
{
/* Clear interrupt enable bits in PCI mode or if the complete 64Kb DPM is available */
if( (ptDevInstance->fPCICard) ||
(ptDevInstance->ulDPMSize == NETX_DPM_MEMORY_SIZE) )
{
/* Disable all interrupts */
HWIF_WRITE32(ptDevInstance, ptDevInstance->ptGlobalRegisters->ulIRQEnable_0, 0);
HWIF_WRITE32(ptDevInstance, ptDevInstance->ptGlobalRegisters->ulIRQEnable_1, 0);
}
}