Critical Link MityCam SoC Firmware  1.0
Critical Link MityCam SoC Firmware
RegisterFile.cpp File Reference

This file contains the tcRegisterFile class. More...

#include <algorithm>
#include <stdlib.h>
#include <stdio.h>
#include <cstring>
#include <fstream>
#include <sstream>
#include <string>
#include <cerrno>
#include <unistd.h>
#include <fcntl.h>
#include <vector>
#include <iostream>
#include <cstdint>
#include <sys/types.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <sys/times.h>
#include <INIReader.h>
#include "Utility/str_funcs.h"
#include "RegisterFile.h"
Include dependency graph for RegisterFile.cpp:

Functions

int char2int (char input)
 
void hex2bin (const char *src, char *target)
 

Detailed Description

This file contains the tcRegisterFile class.

The RegisterFile keeps a "shadow copy" of all of the registers that can be read from an external interface (like GigE or U3V) or from internal logic and deals with endian headaches.

The implementation assumes that when a register is written, the value that it is backing doesn't change. This allows for nearly all register read requests from an external interface to be read back immediately and the wonkiness of endianness is managed consistently in tcRegisterFile. Some bootstrap registers are required to be big endian, etc.

Command handlers (things that care about register writes) must derive from the tcObservable class, register with the tcRegisterFile::registerObserver() and implement a notifyChange() method. All of the command handlers do this (tcAbstractHandler does this, so every command handler does this by default). The general rule (but not really enforced) is that, for any given register write, only one observer should validate it (others may be interested in knowing that it is changing).

If a register value can't be backed by the tcRegisterFile, then you need to implement a tcRegisterFileObserver class and register with the tcRegisterFile::registerReadObserver(). This will allow you to implement a notifyRead() method. This method will get called before a tcRegisterFile::get_array() completes, and allows you to update the value of that register "in real time" before read accesses from extenal interfaces (GenAPI readmem commands) complete. The tcDigitalIOHandler command handler does this to be able to poll the pin IO state "in real time" when a Host tries to read the value for it.

For example, if you are changing the exposure time in code because of something other than a tcRegisterFile::set_value() callback chain (e.g., frame rate change or something similar), then you need to call the tcRegister::update_word() or tcRegister::set_word(), depending. Most times, you would call update_word() as that will just whack the value in the tcRegisterFile backing store (and honor the endianness). set_word() will cause all of the command handler callbacks to be executed. set_word() can be dangerous as you could envision some form of recursion developing.

Right now: Internal ARM code should use the set_XXX, update_XXX, and get_XXX routines to access registers space. All values passed in and out of these routines are in host order (little endian on the ARM).

External interfaces use get_array() for reading memory (the GenAPI readmem command - byte order depends on construction argument) External interfaces use set_XXX() for writing memory (the GenAPI writemem command - host order arguments required, interface classes converting right now)

We should really have a set_array() mechanism for interfaces writing memory so that the interfaces can be endian agnostic, but the reason for it is that we need to allow chained register handlers to be able to validate the requested write operation, and we wanted to limit the endian management to the interface and register file classes only.

Function Documentation

◆ char2int()

int char2int ( char  input)

◆ hex2bin()

void hex2bin ( const char *  src,
char *  target 
)