cifX - Hilscher PCI Vendor and Device IDs (PCI/PCIe Information)

cifX - Hilscher PCI Vendor and Device IDs (PCI/PCIe Information)

Hilscher PCI Vendor and Device IDs (PCI/PCIe Information)

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

CIFX PCI-Register Information

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

Calculating the DPM size from BAR register

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 */

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.

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);
  }
}