KFPA Firmware Documentation

1. Intro

The GBT M&C Manager communicates with the underlying KFPA hardware via the firmware on a Netburner card: http://netburner.com/download/Datasheet-MOD5270-100-200IR.pdf

For interfacing with hardware, instead of using the MCB like the older GBT receiver software does, a Netburner card was choosen. The Netburner card provides modern, network accessible i/o management of hardware interfaces.

On this page we attempt to describe how to work with this card.

2. Setup Instructions For Development

In plain English, here's what you need to do to get setup for development with the Netburner card.

2.1 Parts

  • Netburner card
  • Netburner power adapter
  • Netburner CD (in case software is not installed)
  • computer running Windows (we used GB SDD laptop 'elladan')
  • 2 ethercat cables
  • USB to DB9 cable (USB to serial converter)
  • a network smile

2.2 Setup

  • Install the Netburner software (via CD) if needed
  • Get admin privileges on computer
  • Log on to computer
  • Map a network drive to the source code in your sandbox
    • My Computer -> Tools -> Map Network Drive ...
    • When browsing for the source code on the linux file system, My Network Places -> Ad -> Prospero -> sandboxes ->
    • Map to drive 'Z' for our example
  • Setup the Environment variables we'll need to make (build the 's' file)
    • Right Click 'My Computer', choose properties
    • Advanced Tab -> Environment Variables -> New
      • NBROOT = C\:nburn
      • NBROOTMINGW = C\:nburn
  • Connect all the cables! The Netburner card should get 1) power -> outlet 2) ethercat -> network hub 3) DB9 2 USB -> computer USB
  • Test setup by viewing the card's setup:
    • Windows Start menu -> Netburner NNDK -> Mtty Serial Terminal
    • Mtty should come setup by default:
      • Port is set automatically (ex: COM10)
      • Baud = 115200
      • Parity = None
      • Data Bits = 8
      • Stop Bits = 1
    • click 'Connect'
    • Get ready to type 'A', reboot card by pressing blue button (hold for a second). You have three seconds to abort the startup by clicking 'A'
    • you should now get the 'nb>' prompt
    • type 'setup' * you can read about these options in the docs * note the MAC Address partially matches the serial number found on the card
    • type 'x' to exit
  • type 'help' for ...
  • type 'boot' to watch it ... reboot.

3. Development Workflow

3.1 Edit source code

  • Code is in gbt/devices/receivers/RcvrArray18_26/Firmware
  • Test a change by inserting this print out in user_main.cpp:

void
UserMain(void *pd)
{
  iprintf("Do you see me? ... \r\n");
...
}
  • Commit your change?

3.2 Build source

  • Log on to the windows machine
  • Open 'Command Prompt'
  • Move to the Firmaware directory in your sandbox that you mapped a drive to in the setup
    • chdir /d Z:\mc\gbt\devices\receivers\RcvrArray18_26\Firmware
  • Make!
    • type 'make clean'
    • type 'make'
  • If you get an errors:
    • make sure your master branch is up to date (Pete made some last minute changes to the Makefile)
    • do you have NBROOT* environment variables setup properly
  • Double check that the 'executable' was built properly
    • My Computer -> C:\Nburn\bin
    • The date of 'messageTest_APP.s19' should be updated
    • Note: 'messageTest*' is what gets built due to the NAME setting in the Makefile

3.3 Transfer 'executable' to Netburner card

We have two ways of transferring what we just built to the card:

3.3.1 Serial

  • Get to the 'nb>' prompt: press down card's blue button, and press 'A' on computer as soon as message comes up in Mtty
  • type 'fla' at 'nb>' prompt; should get message 'Begin Down load now ...'
  • Mtty's Transfer menu -> Send File
  • Navigate to C:\Nburn\bin\messageTest_APP.s19
  • You should now see '*'s appear across the Mtty window; when they finish, the card reboots, and the program we just downloaded starts. If you made the iprintf change described above, you should see it now, right after the 'Waiting n sec to start' message.

3.3.2 Ethernet

  • Windows Start Menu -> All Programs -> Netburner NNDK -> Auto Update Tool
  • You should see a dialog with IP Address and FileName. Browse to the same file as above: C:\Nburn\bin\messageTest_APP.s19
    • NOTE on IP Address: As of this writing, the card has a temporary IP address of 199.88.192.167. This needs to get entered into the DHCP.
  • Should download to card much faster then the serial connection
  • Card should reboot and start running new executable as with the serial download

3.4 Debug

  • The source code has a number of '#define's for simulating various parts of the firmware code (to be discussed later)
  • Adding 'iprintf's to the code should show up in Mtty
  • In addition, there is a limited telnet interface that can be used to send commands to the firmware

3.4.1 Telnet

  • First, make sure the card is on the network
    • ping (ex: netburner-03-39-48)
    • the last numbers of this IP address come from the serial number on the card
    • NOTE: this address has not been added to the DHCP yet, so use the temp address of 199.88.192.167 for now
  • telnet
  • log in with any username and password, as long as the two are different
  • the welcome screen has the menu options. For example, type 'reboot' and you should see your card reboot.
  • development:
    • See telnet_server.cpp in the Firmaware directory
    • this was based off the examples in c:/nburn/examples

4. Design

4.1 High Level

One can see from the diagram how the firmware fits in the big picture.
  • Users interact with the KFPA M&C Manager (and the rest of the GBT M&C system) via a program such as Cleo or Astrid.
  • The Manager interacts with the firmware embedded in the Netburner card via sockets transmitting 'messages' as defined at KFPA Comm Protocal.
  • A human can also interact with the firmware via a custom telnet program. Currently this program offers limited functionality.
  • The firmware in turn interacts with the actual KFPA hardware via the I2C commands available from the Netburner SDK
  • In addition, an engineering interface was built using simulink directly to the KFPA hardware which utilizes the I2C standard.

This diagram can be used to visualize how testing can be done by decoupling the firmware from various parts of the system:
  • The firmware can be built to fake interactions with the hardware via the SIMULATE pound-define
  • What does YGOR_SIME pound-define do?

KfpaHighLevel.jpg

4.2 Firmware Code

All code lives in gbt/devices/receivers/RcvrArray18_26/Firmware.

There's a number of classes (~20) in this directory. Many (most?) of them map directly to a sub-device within the KFPA hardware itself, as shown in this diagram. KfpaHardware.jpeg

Without getting into too much details, here's the flow of commands from the M&C Manager to the Firmware down to the hardware.

  • Entry point: user_main.cpp's UserMain:
    • calls initialize()
    • goes to sleep (makes sure we don't exit)
  • Initialize():
    • creates two tasks:
      • message task: for M&C Manager communication
      • telnet task: for telnet communication
  • msgServerTask(): handles and processes all communication with M&C Manager (and subsequent hardware commands)
    • manages socket communications with Manager
    • creates appropriate Datagrams from Manager messages
    • uses Datagrams to create appropriate objects for communicating with hardware
    • objects communicate with hardware via 'monitor' or 'control' methods
    • server stays in infinite loop processing messages from Manager

The messages defined by KFPA Comm Protocal are defined in message_struct.[h,cpp]

Here's a the pattern used by the many classes derived from the Device class:
  • 'send' and 'recv' methods declared in Device.cpp wrap the Netburner's I2C methods for communicating with the hardware.
  • 'monitor' and 'control' methods mentioned above are declared in Device.cpp. in both:
    • the device is locked
    • the virtual doControl/doMonitor method is called
    • the device is unlocked
    • the datagram's success flag is set
  • doControl and doMonitor are virtual methods implemented by these classes.
  • for a typical doControl method:
    • an appropriate message structure is declared
    • the data buffer is passed to the message structure's parse - which appropriate fills the message structure's fields.
    • the fields of the message structure are eventually used to actually send commands to the hardware via 'send' and 'recv'
  • for a typical doMonitor method:
    • state of the hardware is retrieved via 'send' and 'recv'
    • this info is used to appropriately set the fields in the specific message structure defined
    • these fields are then serialized into the datagrams data buffer
  • the parse/serialize methods handle the bit shifting involved in translating between this data buffer and the message structures defined fields (parse puts data in these fields, serialize puts the fields in the data buffer)

4.3 Example

Let's follow an simple example: how the K band wide mode switch is set or monitored.

  • User sets the RcvrArray18_26's KWideBandModeOn parameter to swOn
  • This manager sends, via the socket connection, data as defined in KFPA Comm Protocal
  • In user_main.cpp, this data is converted to a Datagram object. It's id should be set to ID_KMODE_CTRL, as defined in protocol.h (which is defined by the same integer on the Manager side as well)
  • The Datagram's id in turn is used to create a KBandMode object.
  • As described above, this object's doControl is called, with the Datagram's data buffer passed to it.
  • This data buffer contains the state we want to set the kband mode to in the hardware
  • In common.cpp we see what we were describing in the abstract in the above section:
bool
KBandMode::doControl(char *buffer)
{
    int n;
    KBANDMODE_T mode_sel;
    n = mode_sel.parse(buffer);
    //iprintf("KBandMode: %x n_bytes: %d buffer0: %x 1: %x 2: %x 3: %x\r\n", mode_sel.KBandState, buffer[0], buffer[1], buffer[2], buffer[3]);
    return setMasterCal(KMODE_EN, mode_sel.KBandState);
}
  • To repeat what happens, the appropriate message structure is created, and the data buffer is translated into this structures one field, 'KBandState'
  • Then, this field (KBandState) is used to set this bit in the hardware via the super-classe's setMasterCal method:
Kfpa7Device::setMasterCal(unsigned char cal, bool on)
{
    char data[2] = {PORT1, 0x00};
    // Check which bits are set
    bool success = send(MSTR_IOEXP, data, 1);
    success &= recv(MSTR_IOEXP, &data[1], 1);
    // Set new bit
    if(on)
    {
        data[1] |= cal;
    }
    else
    {
        data[1] &= ~cal;
    }
    iprintf("setMasterCal - cal: %x on: %d \r\n", data[1], on);
    success &= send(MSTR_IOEXP, data, 2);
    return success;
}
    • checks with bits are set via 'send' then 'recv' calls to the hardware
    • in the data buffer it got from the previous step, it toggles the appropriate bit to represent our change
    • data is sent back via a 'send' so that the hardware's bit is set.
    • the success of this whole operation is stored in the Datagram's type field
    • the Datagram is serialized back into a buffer and sent back to the Manager so that it will not the state of the last operation

-- PaulMarganian - 2013-01-03
Topic revision: r4 - 2013-01-04, PaulMarganian
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 NRAO Public Wiki? Send feedback