Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

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

 

...

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

...

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

  }

}