Tests on SCU


Important Information

Address of Wishbone Devices

NEVER USE HARD CODED ADDRESSES OF WISHBONE DEVICES Many examples on this wiki page make use of hard coded address for Wishbone devices. This is extremely bad style and almost like hard coding of pointer values in C source code. A typical situation is shown below

[user@scul017f /]# eb-ls dev/wbm0
BusPath        VendorID         Product   BaseAddress(Hex)  Description
1              0000000000000651:eef0b198                 0  WB4-Bridge-GSI     
1.1            000000000000ce42:66cfeb52                 0  WB4-BlockRAM       
1.2            0000000000000651:eef0b198             20000  WB4-Bridge-GSI     
1.2.1          000000000000ce42:ab28633a             20000  WR-Mini-NIC        
1.2.2          000000000000ce42:650c2d4f             20100  WR-Endpoint        
1.2.3          000000000000ce42:65158dc0             20200  WR-Soft-PLL        
1.2.4          000000000000ce42:de0d8ced             20300  WR-PPS-Generator   
...

Another SCU

[user@scul022 /]# eb-ls dev/wbm0
BusPath        VendorID         Product   BaseAddress(Hex)  Description
1              0000000000000651:eef0b198                 0  WB4-Bridge-GSI     
1.1            000000000000ce42:66cfeb52                 0  WB4-BlockRAM       
1.2            0000000000000651:eef0b198             40000  WB4-Bridge-GSI     
1.2.1          000000000000ce42:ab28633a             40000  WR-Mini-NIC        
1.2.2          000000000000ce42:650c2d4f             40100  WR-Endpoint        
1.2.3          000000000000ce42:65158dc0             40200  WR-Soft-PLL        
1.2.4          000000000000ce42:de0d8ced             40300  WR-PPS-Generator   
...

Half a year later

[user@scul022 /]# eb-ls dev/wbm0
BusPath        VendorID         Product   BaseAddress(Hex)  Description
1              000000000000ce42:66cfeb52                 0  WB4-BlockRAM       
2              0000000000000651:eef0b198             80000  WB4-Bridge-GSI     
2.1            000000000000ce42:66cfeb52             80000  WB4-BlockRAM       
2.2            0000000000000651:eef0b198             a0000  WB4-Bridge-GSI     
2.2.1          000000000000ce42:ab28633a             a0000  WR-Mini-NIC        
2.2.2          000000000000ce42:650c2d4f             a0100  WR-Endpoint        
2.2.3          000000000000ce42:65158dc0             a0200  WR-Soft-PLL        
2.2.4          000000000000ce42:de0d8ced             a0300  WR-PPS-Generator   
...

As can be seen, the base addresses of Wishbone devices are not fixed, but depend of the layout of the wishbone bus.

However, what is not subject to change are the VendorID and ProductID. Hence, base addresses should be obtained programmatically. This can be done by using the routine eb_sdb_find_by_identity(..) of the Etherbone library. See https://www-acc.gsi.de/svn/bel/timing/trunk/development/eb_demo/eb_native_demo.c for an example. VendorID and ProductID as well as register layouts of some Wishbone devices can be found here https://www-acc.gsi.de/svn/bel/timing/trunk/development/wb_devices/.

For making Etherbone available on a SCU, please have a look here (look for "Etherbone on the SCU").

Version of a Wishbone Devices

CHECK VERSION OF WISHBONE DEVICES Next to it's base address, the application software must also check if the version of a Wishbone device (and thus the register layout) is correct.
  • Major Version: Whenever the interface is changed, the major version is changed. As an example, if the register layout of a Wishbone device is changed, the major version is changed too. An application must check, if that actual major version of the Wishbone device equals the one against which the application has been developed.
  • Minor Version: Whenever features are just added, the minor version is changed. An application must query the minor version of a Wishbone device and check if it's minor version is equal or older than the one used during the development of the application.
  • On a SCU, versions of Wishbone devices can be checked by using eb-ls in verbose mode, example [user@scul022 /]# eb-ls -v dev/wbm0

Example for the Wishbone Device WR-Endpoint

#include <wr_endpoint.h>
...
  eb_status_t       status;
  eb_device_t       device;
  struct sdb_device sdbDevice;
  eb_address_t      wrEndpoint;
  int               nDevices;
...
  nDevices = 1;
  if ((status = eb_sdb_find_by_identity(device, WR_ENDPOINT_VENDOR, WR_ENDPOINT_PRODUCT, &sdbDevice, &nDevices)) != EB_OK)
    die("EP eb_sdb_find_by_identity", EB_FAIL);
  
  /* check if a unique Wishbone device exists */
  if (nDevices != 1)
    die("expect exactly one endpoint", EB_FAIL);
  /* check version of Wishbone device */
  if (WR_ENDPOINT_VMAJOR != sdbDevice.abi_ver_major)
    die("Endpoint major version conflicting - interface changed:", EB_FAIL);
  if (WR_ENDPOINT_VMINOR > sdbDevice.abi_ver_minor)
    die("Endpoint minor version too old - required features might be missing:", EB_FAIL);
  /* record the address of the device */
  wrEndpoint = sdbDevice.sdb_component.addr_first;

Things to Test


  • TODO
    • Test of all available Timing-Receiver-Methods (etherbone) (Will be provided as soon as we havea WR-Switch connected to the SCU)
      • get current time
      • configure interrupt
      • receive interrupt
    • Test of the Function-Generator-FPGA-Device (Not yet available for etherbone)
    • Test automatic check/load of FPGA-Software (TOBE implemented?)
    • ACU: Ludwig Hechler will do ACU tests as soon as an ACU is available
      1. Write set value, read actual value, read status. (LH, ok)
      2. More than one device per ACU. Needs defined ACU register model!
      3. Generate ramps with ACU function generator. Needs oscilloscope or logic analyzer to check output.
      4. Connect RT-actions with external events (triggers).
      5. Program FTRN and get timing event interrupts. Needs an FTRN and (some sort of) a timing.
      6. A device is triggered by an external trigger. An RT-action must check if there was a triggeran if it was in time.
      7. Detect an overrun.
    • Write a program (that somehow acts like a FESA server action and) that loads a binary to theLM32 soft CPU and starts it.
      • Investigate potentially necessary mutexed slave (ACU) accesses between the SCU CPU and theLM32 soft CPU.
      • Investigate if and how interrupt service routines can be connected with external eventsfrom trigger inputs and from an FTRN.
      • A lm32-gcc is necessary on the asl7xx cluster - more a C than a C++ compiler, right?.

  • DONE
    • Read/Write on FPGA devices via C++ (etherbone)
    • Read/Write on InterfaceCard (etherbone)

Login for SCUs (in the tee-chamber)


  • Just ask Alex, Stefan Rauch or Wesley for login info

  • scul002: with 2 LED slave boards (top)
  • scul007: removed due to HW problems (middle)
  • scul020: with ACU (bottom)


Useful Console Commands


  • lsmod - to get all modules of this linux-kernel
    • check if "wishbone"-modul is loaded
  • eb-ls - to list all etherbone-devices on a port (use -h for help)
    • E.g. # eb-ls dev/wbm0
  • eb-read - to read out data from an etherbone-device
    • E.g. #eb-read dev/wbm0 0x100400/4
  • reboot


Launch lm32 Software


  • Only 1 program can run on the FPGA !
  • load a new program
    • eb-write dev/wbm0/4 0x8 -- puts lm32 into RESET
    • eb-put dev/wbm0 [MyProgram.bin] - loads program
    • eb-write dev/wbm0/4 0x0 -- starts lm32 (removes RESET)


Etherbone Source code



Simple C++ etherbone client


  • What I did until now, using the C++ API can be found here:
  • https://www-acc.gsi.de/viewvc/view/fesa/framework/branches/SCU-Test/
  • To compile the client on the blades & run the client on the SCU, do the following steps:
    • compile the etherbone-core sources for 32bit
    • compile & link the client for 32bit (check etherbone-core pathes in makefile)
    • copy binary to SCU and run it


SCU-Lemos (Digital In-/Output)


The SCU offers 2 Digital In-/Output Lemo-Connectors, which can be accessed from the FESA Class using the Etherbone bus. In order to access them you need to consider following Points:
  • The address of the Lemos is listed as GSI_GPIO_32 and is currently mapped to 0x800000
  • In order to read or write data, Lemos must be switched to In- or Output mode accordingly
    • To set the mode a required value must be written to the register 0x2. The value is interpreted bitwise (1 - IN, 0 - OUT), e.g. 0x3 - sets both connectors to input, 0x1 only first connector is set to input. Default value is 0x0 (both are set to output).
  • Steps to read the value:
    1. Open etherbone socket
    2. Write to the address 0x800004 the value 0x3
    3. Read the value from the address 0x800000
    4. Close etherbone socket


SCU-Display


Simple-Display
Consider using the simple display tool, provided by the timing group. The tool not only supports the OLED display of the SCU but also the LCD display on other timing receivers in a transparent way. Example
#include "disp.h"
...
  eb_device_t device;
...   
  init_disp(device);
  disp_put_s(device, "hello world");
...

Another possibility, see also here
Some SCUs are supplied with display, which for example can be used to write logging messages. The display may be accessed via etherbone bus.
  • Current display base address is 0x900000 and it is descripted as OLED_Display
  • Display has 3 (4) operating modes:
    • 00 : idle
    • 01 : UART - written ASCII code is put directly on the screen
    • 02 : Char - written ASCII code is put on supplied location
    • 03 : Raw - read/write to display memory
  • The mode can be set using the base address, i.e. 0x900000 (write the appropriate value to it)
  • To write something on the display following addresses can be used:
    • 0x00004 : Write resets FSMs and display controller
    • 0x10000 : UART Mode - Written ASCII code is put directly to the screen
    • 0x20000 : Char Mode - Written ASCII code is put on supplied location
      • Address bits(8-6) Char location row
      • Address bits(5-2) Char location column
    • 0x30000 : Raw Mode - Read/Write to display memory
      • Organization is column based, 8px per column
      • Address Bits (12-2) Disp RAM address
  • ASCII code 0x0c (Form Feed) clears the display in mode 1 and 2


ADDAC - Card


The ADDAC - Card (with it IO extension) is providing 3 types of functionality:
  • Reading and converting the analog voltage values (ADC)
  • Output of a supplied voltage level (DAC)
  • Reading (or writing) digital input values of the extention cards (0 - no power, 1 - 5+Volt)
The Communication with the Card is done via the SCU-Bus, which is accessed via etherbone. The card provides following addresses for data exchage:
  • DAC1 : 0x200 (+1 for setting the value)
  • DAC2 : 0x210 (+1 for setting the value)
  • IO : 0x220
  • ADCn : 0x230 + n
The base address of the ADC (ADC0) can be used to configure the ADC. The configuration is done via single byte value, where bits have following meanings:
  • 0 : reset
  • 1 : active
  • 2..1 : 00-> paralell, 01->seriell
  • 3 : range, 1 - (-10/+10 V, default), 0 - (-5/+5 V)
  • 4 : n.e.
  • 7..5 : oversampling mode, 000 - no OS, 110 ratio 64
  • 8 : diff input 3..8


Etherbone Adapter


TODO: The internal API for the Etherbone Adapter has been changed a bit, so the examples below will not work and need an update

Etherbone Adapter is a small API to ease the access to etherbone bus from the FESA classes. The API is basicly an Object-Oriented wrapper over the "standard" etherbone framework. It also contains classes with some basic utility functions and an DisplayAdapter to write messages to the display.

The API can be found here (SVN): https://www-acc.gsi.de/svn/fesa/device/driver/EtherboneAdapter. Additionaly a tar.gz is attached to this section

Some examples how to use it whithin a fesa class:

Read example (read from ADDAC card):
std::string etherboneDevicePort = "dev/wbm0";     // device port
uint32_t baseAddress = 0x400000;                  // etherbone address to access
uint32_t registerAddress = 0x231;                 // address of particular device register (e.g. 0x230 for ADDAC cards ADC1)
int slaveNumber = 5;                              // Slave number of the card (needed only for SCU-Bus cards)

// Calculates the actual address of the device (baseAddress + 2^15 * slaveNR + 2 * registerAddress)
uint32_t readAddress = etherbone::EtherboneHelper::calculateAddress(baseAddress, slaveNumber, registerAddress);

// Get the adapter
etherbone::EtherboneAdapter myAdapter(etherboneDevicePort, readAddress);

myAdapter.open();                                   // open connection
uintptr_t someRawValue1 = myAdapter.readInt();      // read value from readAddress
uintptr_t someRawValue2 = myAdapter.readInt(0x2);   // read value with an offset of 0x2: readAddress + offset (corresponds to ADC2 in this case)
myAdapter.close();                                  // close connection

Write example:
//Some address initializaion like in the example above
...

// get the adapter
etherbone::EtherboneAdapter myAdapter(etherboneDevicePort, writeAddress)
myAdapter.open();                     // open connection
myAdapter.writeInt(data);             // write data to the base writeAddress
myAdapter.writeInt(data, offset);     // write data with an offset writeAddress+offset
myAdapter.close();                    // close connection

Display usage example:
// Some message
std::stringstream; 
message << "Read value equals: ";
message << someValue;

etherbone::DisplayAdapter display(etherboneDevicePort);  // get the display adapter
display.init();                                          // init the adapter
display.reset();                                         // clear the content of the display
display.print(message.str());                            // print a message on the display
display.close();                                         // close connection

To use the API with an FESA class the Makefile.specific files of Class and DeployUnit Projects need to be modified:
EB_HOME = /home/bel/rapp/lnx/git/etherbone-core/api
EB_INCL = -I$(EB_HOME)
EB_LIBS = -L$(EB_HOME) -letherbone

EB_ACC_HOME = /common/home/bel/rapp/lnx/workspace/EtherboneAdapter
EB_ACC_INCL = -I$(EB_ACC_HOME)
EB_ACC_LIBS = -L$(EB_ACC_HOME) -libetherbone-adapter
# for DeployUnit
#EB_ACC_STATIC_LIB = $(EB_ACC_HOME)/etherbone-adapter.a

COMPILER_FLAGS += $(EB_ACC_INCL) $(EB_INCL)
LINKER_FLAGS += $(EB_ACC_LIBS) $(EB_LIBS)
# for DeployUnit
# LINKER_FLAGS += $(EB_ACC_STATIC_LIB) $(EB_LIBS)


Misc


  • GSI_GPIO_32 is one of the devices, which makes the SCU blinking
  • Dont touch GSI_CFI_FLASH_32
  • The LED-slaves use a big-endian, so you have to use EB_BIG_ENDIAN when sending data
I Attachment ActionSorted ascending Size Date Who Comment
Email_SCU_Slaves.txttxt Email_SCU_Slaves.txt manage 1 K 03 Aug 2012 - 12:47 AlexanderSchwinn Describes how to talk to slave-cards
EtherboneAdapter.tar.gzgz EtherboneAdapter.tar.gz manage 12 K 16 May 2013 - 09:08 VitaliyRapp Etherbone Adapter API
MakefileEXT Makefile manage 3 K 06 Aug 2012 - 12:44 AlexanderSchwinn Modified EB-Makefile with -m32 flags
Wishbone-core-api.pdfpdf Wishbone-core-api.pdf manage 331 K 05 Jun 2012 - 14:06 AlexanderSchwinn partly out-dated etherbone-doku
scu_echo_test.hh scu_echo_test.h manage 1 K 02 Aug 2012 - 15:15 AlexanderSchwinn Information about SCU-Master Registers and Registers of its slave-cards
Topic revision: r35 - 22 May 2015, DietrichBeck
This site is powered by FoswikiCopyright © by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding Foswiki? Send feedback