GLAST / LAT > DAQ and FSW > FSW > Doxygen Index> LCBD / dev > lcbd / mv2304
Inevitably there are rough spots where these three units are not completely orthogonal. Ideally one could choose to independently load any combination of these, ignoring the others. The rough spots surface when ensuring that units not of interest are in a quiet state.
A brief summary of these files is presented in the following table. They are presented roughly in order of usage and importance.
Functional Unit | What it does | Header Files | Source Files
|
Driver | Driver load/unload plus interrupt connection and enables | LCBD_drv.h | LCBD_drv.c
|
Clock | Signals transitions of the 20MHz LATp-side clock | LCBD_clk.h | LCBD_clk.c
|
Notification | Asynchronous notification of driver state transitions | LCBD_nut.h | LCBD_nut.c
|
Command/Response | Submits command lists and handles result lists | LCBD_rst.h | LCBD_rst.c
|
Event | Handles incoming traffic on the event fabric | LCBD_evt.h | LCBD_evt.c
|
Statistics | Fetching and displaying of driver statistics | LCBD_stats.h | LCBD_stats.c
|
Driver Command/Result Lists | Lays out LCBD structure for both command & result lists | LCBD_cr.h | - none -
|
Command Utilities | Simple filling, parsing and synchronous execution of command lists and items | LCBC.h | LCBC.c
|
Result Utilities | Parsing and traversing of result lists and items | LCBR.h | LCBR.c
|
MSG Codes | MSG message code definitions | LCBD_msgs.h | - none - |
Hardware Unit | What it does | Header Files
|
LCB Definitions | Defines global LCB hardware properties | LCB.h
|
LCB Command/Result List & Items | Defines command and result lists and items plus opcodes | LCB_cr.h
|
LATP | LAT protocal definitions | LATP.h |
Function | Description
|
LCBD_allow | Allows one to add additional PCI/LATp FPGA versions. Mainly used in testing new versions of the FPGAs were being developed
|
LCBD_create | Creation and software pre-initialization of the drive handle, one-time only call
|
LCBD_get | Returns a pointer to the driver handle
|
LCBD_load | Loads the driver
|
LCBD_unload | Unloads the driver
|
LCBD_enable | Enables/Disables the various interrupt sources
|
LCBD_state_get | Gets the current state of the driver
|
LCBD_drain | Drains the result and/or event queues (non-interrupt mode)
|
LCBD_pci_cfg_status_clear | Clears the status bits in the PCI configuration status register
|
LCBD_dib_locate | Returns a pointer to the Device Information Block
|
LCBD_dib_show | Displays the contents of the Device Information Block |
The LCB hardware contains two related interrupts, one indicating the transition from the clock being off to the clock being on, and one indicating the opposite transition from the clock being on to the clock being on. It is expected that the system will install appropriate callback routines to handle these transitions. But these callback routines are very primitive, really meant for debugging and development purposes. A higher level facility based on the clock interrupts is provided, the Notification of the User of state Transitions (NUT) facility.
Function | Description
|
LCBD_clk_off_cb_set | Seeds the clock off callback routine + parameter
|
LCBD_clk_off_cbp_get | Returns the clock off callback routine + parameter
|
LCBD_clk_on_cb_set | Seeds the clock on callback routine + parameter
|
LCBD_clk_off_cbp_get | Returns the clock on callback routine + parameter
|
Function | Description
|
LCBD_nut_handler_create | Convenience routine to create the NUT service task and set the FORK_que
|
LCBD_nut_que_install | Installs the NUT FORK que
|
LCBD__nut_fill | Convenience routine to fill a notification request
|
LCBD_nut_notify | Ques a notification request
|
LCBD_nut_cancel | Cancels a notification request |
Function | Description
|
LCBD_nut_notifyW | Ques a notification request and waits for till it is satisfied
|
LCBD_nut_head_create | Creates a pending list head to use with LCBD_nut_post and LCBD_nut_pendW
|
LCBD_nut_head_destroy | Destroys the specified nut post head created with LCBD_nut_head_create
|
LCBD_nut_post | Ques a notification request and ques the satisfied request to the specified posting head
|
LCBD_nut_pendW | Pends of a NUT post head for the next satisfied notification request
|
LCBD_nut_fork | Ques a notification request and ques the satisfied request to the specified FORK que
|
For those truly interested, while the LCB obeys a FIFO principle of operations, it is highly buffered and pipelined. The LCB can have operations pending in a variety of states within it. While the counting is not exact, the LCB could have on the order of 8-10 command lists in or waiting for execution. One of the simplications of the LCB hardware was to not provide a cancel function. Once an operation has been successfully submitted to the LCB hardware, it cannot be recalled.
To understand the importance of the above statement it necessary to know
The answer to the first is straight-forward. The bus will be snooped during any read operation to ensure that the data being read is in memory and not in the CPU cache. The answer to the second is not straight-forward and the detailed answer is dependent on whether on is talking about a command list or a result list.
It is clear that when the LCB DMAs a command list from memory into its internal buffers, read operations, and, therefore, bus snoops are occuring. What is not as clear is
The reason the result list needs protecting can be traced back to the need and method used to flush the bridge chips internal buffers. Whether by design or due to an error, any DMA transfer that writes data back into the memory that is not a integral multiple of cache lines, needs a dummy read operation to flush the partial cache line remnant back into memory. It is this read operation that generates a bus snoop and, therefore, makes the result list vulnerable to the bus hang. Also the partial flush itself generates a bus snoop since it must snoop the bus to cast out any dirty copy of the cache line it is about to partially write.
The definition of the vulnerable memory is also tricky. When this problem was first encountered and addressed, the answer seemed straight-forward. It is the memory occupied by the command or result lists rounded up to the nearest cache line boundary. This turned out to be only partially correct. For efficiency reasons, the bridge chip attempts to keep a buffer of 6 cache lines filled at all times. Effectively as soon as one or more cache lines are consumed, the bridge chip fetches enough data to replace it. This means that the vulnerable area is much larger than one naively would think.
Therefore, the allocation strategy for command lists is allocate an additional 5 cache lines after the end of the last cache line in the command list.
Therefore, the allocation strategy for result lists to be rounded up to a cache line boundary and to always ensure that a minimum of 6 cache lines are allocated. Note that when allocating LCBD result lists, these include the driver defined and mandated structure LCBD_xcb, so the size of this structure must added to the minimum hardware size. This means the minimum size of a DMA-safe LCBD_rl is the sizeof its LCBD_xcb plus its LCB_rl_hdr + its items.
In addition, if the user truly needs to size the list at compile-time, two macros are provided
However, where, possible, the user is encouraged to use the run-time routines, as these provide protection if there is yet another change in what constitutes a safe allocation.
As previously alluded to, there are macros and routines that define the alignment and padding necessary for the user to size and allocate custom lists. These, in fact, are the ingredients that the LCBD software itself uses, so there is nothing it can do that a user of the software cannot recreate. Having said that, the downside of doing it yourself is that policy is moved from the centralized LCBD software out into the wild of many packages. The result is that code is vulnerable if the details of how to produce safe lists changes. Note that there are, in general, three kinds of safety
Function | Description
|
LCBD_rst_handler_create | Convenience routine to create the RST service task and set the FORK_que
|
LCBD_rst_que_install | Installs the RST FORK que
|
LCBD_rst_null_cb_set | Seeds the NULL result descriptor handler + parameter
|
LCBD_rst_null_cbp_get | Returns the NULL result descriptor handler + parameter
|
LCBD_bind | Binds the parameters of an LCBD_xcb to the XCB
|
LCBD_submit | Submits a bound LCBD_xcb to the LCB for execution |
Function | Description
|
LCBD_cl_size | DMA-safe command list size determination
|
LCBD_rl_size | DMA-safe result list size determination
|
LCBD_cl_alloc | DMA-safe command list allocator, by bytes
|
LCBD_rl_alloc | DMA-safe result list allocator, by bytes
|
LCBD_cl_alloc8 | DMA-safe command list allocator, by 8 byte cells
|
LCBD_rl_alloc8 | DMA-safe result list allocator, by 8 byte cells |
LCBD_cl_alloc_unprotected | Unprotected command list allocator, by bytes
|
LCBD_rl_alloc_unprotected | Unprotected result list allocator, by bytes
|
LCBD_cl_alloc8_unprotected | Unprotected command list allocator, by 8 byte cells
|
LCBD_rl_alloc8_unprotected | Unprotected result list allocator, by 8 byte cells
|
LCBD__cl_len | Converts a command list length in bytes to 8-byte cells, i.e. something suitable to passing to one of the LCBD_bind routines
|
LCBD__cl_dlen | Converts a command list specified by it's beginning and ending pointers to 8-byte cells, i.e. something suitable to passing to one of the LCBD_bind routines
|
LCBD__rl_len | Converts a result list length in bytes to 8-byte cells, i.e. something suitable to passing to one of the LCBD_bind routines
|
LCBD__rl_dlen | Converts a result list specified by it's beginning and ending pointers to 8-byte cells, i.e. something suitable to passing to one of the LCBD_bind routines
|
LCBD_rst_rcv_err_map | Translates a result list receive error code to a standard MSG code
|
LCBD_rst_xfr_err_map | Translates a result list transfer error code to a standard MSG code
|
Function | Description
|
LCBD_qioW | Convenience routine to que a command list to the LCB and wait for its completion, combines LCBD_bind and LCBD_submitW
|
LCBD_submitW | Submits a bound LCBD_xcb to the LCB and waits for its completed execution
|
LCBD_fork_bind | Binds the parameters to an LCBD_xcb using a dispatch to a FORK que as its synchronization method.
|
LCBD_post_create | Creates a posting list head that can be used by LCBD_post_bind and LCBD_post_pendW
|
LCBD_post_destroy | Destroys the posting list head created by LCBD_post_create
|
LCBD_post_bind | Binds the parameters of the LCBD_xcb to an XCB using a dispatch to a posting list head as its synchronization method.
|
LCBD_post_pendW | Waits for the next completed LCBD_xcb on the specified posting list head |
Macro | Description |
LCBD_CL_ALIGN | The byte alignment requirement for command lists. This can be used as the first argument to MBA_align.
|
LCBD_RL_ALIGN | The byte alignment requirement for result lists This can be used as the first argument to MBA_align.
|
LCBD_CL_PAD | The size, in bytes, of the padding needed after the last cache line of a command list.
|
LCBD_RL_MIN | The minimum size, in bytes, of result list.
|
LCBD_RNDUP_TO_CACHELINE | Rounds a specfied number of bytes up to the nearest cache line boundary.
|
LCBD_RNDDOWN_TO_CACHELINE | Rounds a specfied number of bytes down to the nearest cache line boundary.
|
LCBD_EXP_DSC_COMPOSE | Composes a complete command export descriptor
|
LCBD_EXP_DSC_REPLACE_LEN | Replaces only the length field of a command export descriptor |
Outbound traffic, e.g. a LCB-to-LCB message, is really part of the command/response unit, not the event unit. To the receiver, such transactions are a part of the event unit, but to the transmitter they are handled by the command/response unit.
Function | Description
|
LCBD_evt_handler_create | Convenience routine to create the EVT service task and set the FORK_que
|
LCBD_evt_que_install | Installs the EVT FORK que
|
LCBD_evt_cb_set | Seeds the event callback handler + parameter for a specified protocol
|
LCBD_evt_cbp_get | Returns the event callback handler + parameter for a specified protocol
|
LCBD_evt_err_cb_set | Seeds the event error handler + parameter for a specified
|
LCBD_evt_err_cbp_get | Returns the event error handler + parameter
|
LCBD_evt_conds_set | Sets the event que and event buffer interrupt conditions, returning the old ones, see LCBD_EVT_COND
|
LCBD_evt_enable | Enables the flow of events into the event circular buffer, returns the original flow state
|
LCBD_evt_tickle | Tickles the event handler to check if there are any events to be serviced.
|
LCBD_evt_free | Frees the specified event
|
LCBD_evt_rcv_err_map | Translates a event receive error code to a standard MSG code
|
LCBD_evt_xfr_err_map | Translates a event transfer error code to a standard MSG code |
Special sentinel values allow both parameters to be ignored, that is the LCB will not attempt to set them. Correct use of the fabric select parameter is highly dependent on whether the LCB is residing in a SIU or EPU crate.
to LCBD_load. Because the primary boot code does not use the LCB, this value is not needed until secondary boot. The secondary boot code should use the EEPROM to store this value. If fail-over is needed, then a 1553 command will be issued to change it.
The former instructs LCBD_load to leave the event base register as is. This may be valuable in test code. The latter instructs LCBD_load to internally allocate a buffer and use its address as the event base. Buffers automatically allocated will be freed when the driver is unloaded. Clean-up of user specificed buffers is the responsibility of the user.
See the enum LCBD_LOAD_OPTIONS_M and the macro LCBD_LOAD_OPTIONS_M_BOARD_ID_N for details.
Specifying these parameters in this way is only a convenience. The loading of the does not depend on these parameters in any way. Because it is not absolutely necessary to load these parameters at this time and because it is possible that the application does not know the value of these parameters at LCBD_load time, they can be set at anytime before they are needed (general rule here is before any external LCBD operations are attempted such as issuing a message to another CPU or talking to a TEM), there are convenience routines to set them at a later point. These are
The first class of users are test code writers and prototypers. The second class of users are those installing the driver in a deliverable product. Needlessly to say, satisfying both groups simoultaneously is difficult.
For user's in the second class, LCBD provides three routines to register these ques with the driver
Naturally, the user is responsible for creating the FORK task and identifying the target que. With this responsibility comes the freedom to do almost anything one pleases. For example, one could create one FORK task with 3 ques, handing a different que to each installation routine. (Would not recommend this.)
For user's in the first class, a simplified set of routines to create a FORK task and install a FORK que are provided. (These routines may be stripped from the final production driver; they consume are fair amount of code space.) These routines are
The priority can be specified with a sentinel values
If so, LCBD will assign a handler specific priority to each FORK task.
With this simplication, one loses control of almost every parameter of the FORK task (except the priority). If special attributes, such as a larger stack, the floating point unit, more ques, etc, are needed, the user must create the FORK task and install the que using the previously described method.
As a convenience to the user, any service tasks created using convenience routines (e.g. LCBD_rst_handler_create) will be destroyed. It is the user's responsibility to manage the tasks associated with, e.g. LCBD_rst_que_install; afterall the LCBD que may be only one of many ques associated with this task. As mentioned before, if the event circular buffer is allocated by the driver, it will also be freed by LCBD_unload operation.
unsigned int startLcbd (unsigned int options, unsigned int *circularBuffer) { // Get pre-initialized driver handle lcb = LCBD_create (NULL); // Load the driver, // Options is used to select the path and the interrupt source // See LCBD_LOAD_OPTIONS_M for details status = LCBD_load (lcb, options, circularBuffer); // Install the result, event and notification service tasks // using the default priorities status = LCBD_rst_handler_create (lcb, LCBD_RST_K_DEFAULT_PRIORITY); status = LCBD_evt_handler_create (lcb, LCBD_EVT_K_DEFAULT_PRIORITY); status = LCBD_nut_handler_create (lcb, LCBD_NUT_K_DEFAULT_PRIORITY); // Set the callback handler for the protocol #1 status = LCBD_evt_cb_set (lcb, 1, eventHander, eventParameter); // Set event interrupt conditions 25% on FIFO LCBD_evt_conds_set (lcb, LCBD_EVT_COND_25_FULL); // Enable the result and event interrupts status = LCBD_enable (lcb, LCBD_M_ENABLE_EVENT | LCBD_M_ENABLE_RESULT)); // Enable the event flow into the LCB's circular buffer status = LCBD_evt_enable (lcb, 1); return status; }
unsigned int startLcbd (unsigned int options, unsigned int *circularBuffer, FORK_que *evt_que, FORK_que *nut_que, FORK_que *rst_que) { // Get pre-initialized driver handle lcb = LCBD_create (NULL); // Load the driver // Options is used to select the path and the interrupt source // See LCBD_LOAD_OPTIONS_M for details init_status = LCBD_load (lcb, options, circularBuffer); // Check for success errors if (_msg_error (init_status) return init_status; // Install the result, event and notification ques status = LCBD_rst_que_install (lcb, rst_que); status = LCBD_evt_que_install (lcb, evt_que); status = LCBD_nut_que_install (lcb, nut_que); // Enable the clock on interrupt // The only possible error is if one tries to simoultaneously set // both the ENABLE and DISABLEs, clearly not happening here LCBD_enable (lcb, LCBD_M_ENABLE_CLK_ON); // Check if possibly have no clock if (init_status == LCBD_NOCLK) { LCBD_state state; // Wait for the driver to come online // Once ONLINE the driver has been successfully initialized // Keep in mind it may on OFFLINE at any time in the future, // but in terms of initialization, it's done. state = LCBD_nut_notifyW (lcb, LCBD_STATE_M_ONLINE); } // Set the callback handler for the protocol #1 status = LCBD_evt_cb_set (lcb, 1, eventHander, eventParameter); // Set event interrupt conditions 25% on FIFO full LCBD_evt_conds_set (lcb, LCBD_EVT_COND_25_FULL); // Enable the result and event interrupts status = LCBD_enable (lcb, LCBD_M_ENABLE_EVENT | LCBD_M_ENABLE_RESULT)); // Enable the event flow into the LCB's circular buffer status = LCBD_evt_enable (lcb, 1); // Check driver state, not necessary, but just to illustrate return (LCBD_state_get (lcb) == LCBD_STATE_ONLINE) ? status : ERROR; }
The second item is a corollary of the first. Here is an example of a statically defining the command list and dynamically allocating and filling it. Note that many of the intermediary structures are unnecessary, but the example wishes to illustrate, in a very pedantic fashion, how fully specify command and result lists are built from the available components.
// Define the command items typedef struct _MyCmdItems { LCB_ci_mark_time mark1; // Issue a mark time command LCB_ci_csr csr; // Read the LATp-side CSR LCB_ci_mark_time mark2; // Issue another mark time command LCB_ci_faults faults; // Read the LATp-side FAULTs register } MyCmdItems; // Assemble into a command list typedef struct _MyCmdList { LCB_rl_hdr *hdr; // Reserved for the result list address MyCmdItems ci; // The command items } MyCmdList; // Define the corresponding result items typedef struct _MyRstItems { LCB_ri_mark_time mark1; // Result item for mark time command 1 LCB_ri_csr csr; // Result item for CSR access LCB_ci_mark_time mark2; // Result item for mark time command 2 LCB_ci_faults faults; // Result item for FAULTS register access } MyRstItems; // Assemble into a hardward result list typedef struct _LcbRstList { LCB_rl_hdr hdr; // LCB result list header MyRstItems ri; // The result items } LcbRstList; // Tack on the XCB that the driver needs typedef struct MyRstList { LCBD_xcb xcb; // The XCB control structure LcbRstList rl; // The LCB result list } MyRstList; LCBD_post_head head; // Synchronizing que head LCBD_xcb *xcb; // Allocate these // This could also be done off the stack (obeying proper alignment) MyCmdList *cl = LCBD_cl_alloc (sizeof (MyCmdList)); MyRstList *rl = LCBD_rl_alloc (sizeof (MyRstList)); // Use the inlines to fill the commands although the structures of // each command are exposed, so you could 'do it yourself' LCBC__mark_time_fill (&cl.ci.mark1, 200); LCBC__csr_access_fill (&cl.ci.csr, val, select, timeout); LCBC__mark_time_fill (&cl.ci.mark2, 400); LCBC__faults_access_fill (&cl.ci.cfaults, 0, -1, timeout); LCBD_post_create (lcb, &head) // Bind these parameters to a posting que synchronization method xcb = LCBD_post_bind (lcb, LCBD__cl_len (sizeof (*cl)), cl, LCBD__rl_len (sizeof (&rl->rl)), rl, &head, 0, 0, 0, 0); // Submit the transaction // Of course once the XCB transaction has been built, it can // be submitted at any later time. LCBD_submit (lcb, &xcb); // Wait for completion... // Again, there could be an arbitrary amount of code between the // LCBD_submit and the pending. (Warning, at least in this example // this memory for head is allocated on the stack, so the submission // and wait must be in this routine.) xcb = LCBD_post_pendW (lcb, &head);
The nature of the statistics is explained in detail in LCBD_stats.h. From a more global perspective, the statistics are almost completely interlocked. That is, almos all consistency checks that can be performed without shutting down the driver. For example, without any special care, one can get a checksum over the number of transaction
Function | Description
|
LCBD_stats_clr | Clears the statistics counters
|
LCBD_stats_get | Gets a copy of the statistics counters
|
LCBD_stats_sub | Subtracts two sets of statistics counters
|
LCBD_stats_isr_show | Displays the ISR statistics counters
|
LCBD_stats_evt_show | Displays the EVENT statistics counters
|
LCBD_stats_rst_show | Displays the RESULT statistics counters
|
LCBD_stats_show | Displays the all the statistics counters |
There are four groups of routines
Function | Description
|
LCBC_process | Convenience routine to execute a user callback routine for each command item
|
LCBC_show | Convenience routine to display each command item |
Function | Description
| |
LCBC_mark_time | Convenience routine to fill a mark time command item
| |
LCBC_cmd_xmit | Convenience routine to fill a LAT reset command item |
|
LCBC_lat_reset | Convenience routine to fill a command transmit with no response command item
| |
LCBC_cmdr_xmit | Convenience routine to fill a command transmit with response command item
| |
LCBC_csr_access | Convenience routine to fill a LATp-side CSR access command item
| |
LCBC_faults_access | Convenience routine to fill a LATp-side FAULTS register access command item |
Function | Description
|
LCBC_mark_time_fill | Convenience routine to fill a mark time command item
|
LCBC_event_fill | Convenience routine to fill a event transmit command item
|
LCBC_cmd_xmit_fill | Convenience routine to fill a LAT reset command item
|
LCBC_lat_reset_fill | Convenience routine to fill a command transmit with no response command item
|
LCBC_cmdr_xmit_fill | Convenience routine to fill a command transmit with response command item
|
LCBC_csr_access_fill | Convenience routine to fill a LATp-side CSR access command item
|
LCBC_faults_access_fill | Convenience routine to fill a LATp-side FAULTS register access command item |
Function | Description
|
LCBC__mark_time_fill | Convenience routine to fill a mark time command item
|
LCBC__event_fill | Convenience routine to fill a event transmit command item
|
LCBC__cmd_xmit_fill | Convenience routine to fill a LAT reset command item
|
LCBC__lat_reset_fill | Convenience routine to fill a command transmit with no response command item
|
LCBC__cmdr_xmit_fill | Convenience routine to fill a command transmit with response command item
|
LCBC__csr_access_fill | Convenience routine to fill a LATp-side CSR access command item
|
LCBC__faults_access_fill | Convenience routine to fill a LATp-side FAULTS register access command item |
Note that one of the command types is LCBC_TYPE_UNDEFINED. This can be used to validate the opcode. Since the length is explicitly stored in a command item, there are no macros to translate an OPCODE to a length.
The mapping macros come in two flavors, depending on whether one explicitly specifies the mapping word or lets the macro implicitly reference it. The latter is more efficient when the mapping word is used many times, saves reloading it each time, the former is just more convenient. Note that one must use LCBC in relation to command items, not result items. The type or length of a command item is not necessarily the same as the type or length of its corresponding result item.
Macro | Description
|
LCBC_TYPE_BY_OPCODE_FULL | Translates an opcode to a command item type, mapping word is explicitly specified
|
LCBC_TYPE_BY_OPCODE | Translates an opcode to a command item type, mapping word is implicit |
The driver wishes to maintain its distance from dealing with the individual result items. The routines in LCBR were written because they provide functionality of widespread interest. They were bundled in with the LCBD package for lack of a better place. (They are really not part of the driver, but they have no other good home.) Note that one must use LCBR in relation to result items, not command items. The type or length of a result item is not necessarily the same as the type or length of its corresponding command item.
Function | Description
|
LCBR_check | Convenience routine to check each result item for errors
|
LCBR_error_get | Convenience routine to get the error word for a result item
|
LCBR_process | Convenience routine to execute a user callback routine for each result item
|
LCBR_show | Convenience routine to display each result item |
Note that one of the result types is LCBR_TYPE_UNDEFINED. This can be used to validate the opcode.
The mapping macros come in two flavors, depending on whether on explicitly specifies the mapping word or lets the macro implicitly reference it. The latter is more efficient when the mapping word is used many times, saves reloading it each time, the former is just more convenient.
Macro | Description
|
LCBR_TYPE_BY_OPCODE_FULL | Translates an opcode to a command item type, mapping word specified
|
LCBR_TYPE_BY_OPCODE_FULL | Translates an opcode to a result item type, mapping word is implicit
|
LCBR_N8BYTES_BY_OPCODE_FULL | Translates an opcode to a result item length in 8-byte cells, mapping word is specified
|
LCBR_N8BYTES_BY_OPCODE | Translates an opcode to a result item length in 8-byte cells, mapping word is implicit |
Macro | Description
|
LCB_CI_HDR | Composes the command item header word
|
LCB_CI_CMD | Composes the a transmit command item initializing data statement
|
LCB_CI_MARK_TIME | Composes the a mark command item initializing data statement
|
LCB_CI_LAT_RESET | Composes the a lat reset command item initializing data statement
|
LCB_CI_CSR | Composes the a csr access command item data statement
|
LCB_CI_FAULTS | Composes the a faults command item data statement
|
LCB_CI_EVENT_LEN_32 | Rounds a specified number of integers to the next highest LATP number of cells, returning the answer in integers. Useful for specifying the length to a Event Transfer Command
|