Attention: The SUBSYSTEM_ID is used to determine if the hardware is a RAM based or FLASH based hardware
- 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!
CIFX50 / CIFX70 / CIFX90 etc. | ||
---|---|---|
PCI Identifier | Value | Description |
VENDOR_ID | 0x15CF | Hilscher GmbH |
DEVICE_ID | 0x0000 | CIFX |
SUBVENDOR_ID | 0x0000 | none |
SUBSYSTEM_ID | 0x0000 | none |
netPLC | |||
---|---|---|---|
PCI Identifier | Value RAM based | Value FLASH based | Description |
VENDOR_ID | 0x15CF | 0x15CF | Hilscher GmbH |
DEVCE_ID | 0x0010 | 0x0010 | netPLC |
SUBVENDOR_ID | 0x15CF | 0x15CF | Hilscher GmbH |
SUBSYSTEM_ID | 0x0000 | 0x0001 | RAM/FLASH based |
netJACK | |||
---|---|---|---|
PCI Identifier | Value RAM based | Value FLASH based | Description |
VENDOR_ID | 0x15CF | 0x15CF | Hilscher GmbH |
DEVCE_ID | 0x0020 | 0x0020 | netJACK |
SUBVENDOR_ID | 0x15CF | 0x15CF | Hilscher GmbH |
SUBSYSTEM_ID | 0x0000 | 0x0001 | RAM/FLASH based |
PCI Register Information | ||
---|---|---|
Base Address Register | Definition | Description |
BAR 0 | DPM_BASE_ADDRESS | CIFX Dual Ported Memory (DPM) |
BAR 1 | TARGET_BASE_ADDRESS | MRAM area (if suporrted by hardware) |
BAR 2 | I/O_BASE_ADDRESS | unused (special netX feature) |
BAR 3 | 0 | unused |
BAR 4 | 0 | unused |
BAR 5 | 0 | unused |
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.
- save the current BAR content (this is the physical memory address)
- fill all bits of the BAR register with "1" (0xFFFFFFFF)
- read the BAR content back (Memory Information value)
- restore the BAR with the previous saved original value (physical memory address)
- compute the size from the "Memory Information" value
- This is done by masking out the lowest 4 bit for a memory BAR (2 bit for a I/O BAR) and building the two's complement of the value (invert the value and add 1).
The resulting value is the memory size in bytes.
if (val & 1)
size = (~val | 0x3) + 1; /* I/O space */
else
size = (~val | 0xF) + 1; /* memory space */
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.
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;
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);
}
}