AXIS                             ETRAX100               $Revision: 1.2 $
COMMUNICATIONS AB           Programmer interface        Date: Oct 15 1999
Jan Bengtsson                 sv_shadow.axw             Page:1(38)




















                                ETRAX100

                            Programmer interface

         $Id: hwregs.html,v 1.2 2000/09/26 14:56:36 jonashg Exp $

0. TABLE OF CONTENTS

0. TABLE OF CONTENTS................................................. 2 1. References......................................................... 4 2. Introduction....................................................... 4 2.1 Purpose of shadow registers.................................... 4 2.2 Multiple interfaces of the same type........................... 6 3. Interface.......................................................... 6 3.1 Common macro parameters........................................ 6 3.1.1 i (interface number)................................ 6 3.1.2 reg (register name)................................... 6 3.1.3 field (register field name)............................. 6 3.1.4 val (value)........................................... 7 3.1.5 var (variable name)................................... 7 3.2 Definitions.................................................... 7 3.2.1 field width............................................... 7 3.2.2 register width............................................ 7 3.2.3 return value.............................................. 7 3.2.4 LSB....................................................... 7 3.2.5 Register group............................................ 8 3.3 REG_GET Read a field in a register.......................... 9 3.4 REG_IGET Read a field in a register.......................... 10 3.5 REG_VGET Read a field in a variable.......................... 11 3.6 REG_SET Write a field in a register......................... 12 3.7 REG_ISET Write a field in a register......................... 13 3.8 REG_VSET Write a field in a variable......................... 14 3.9 REG_SET_VAL Write an integer value to a symbolic field....... 15 3.10 REG_SET__register-name Write to all fields at one time....... 16 3.11 REG_SET__register-name__SHADOW Write to all fields at once... 17 3.12 REG_MASK__register-name Create a mask........................ 18 3.13 REG_VAL__register-name Create an integer value............... 19 3.14 REG_EQL Compare a field in a register....................... 20 3.15 REG_IEQL Compare a field in a register....................... 21 3.16 REG_VEQL Compare a field in a variable....................... 22 3.17 REG_VAL Convert a symbolic value to an integer value........ 23 3.18 REG_CHK_VAL Check an integer value against field range....... 24 3.19 REG_RD Read complete register.............................. 25 3.20 REG_IRD Read complete register.............................. 26 3.21 REG_WR Write complete register............................. 27 3.22 REG_IWR Write complete register............................. 28 3.23 REG_ADDR Address to a register............................... 29 3.24 REG_BITNR Least significant bit in a field.................... 30 4. Initialization..................................................... 31 5. Selecting register groups.......................................... 31 6. Debug mode......................................................... 31 6.1 User defined error action...................................... 32 6.1.1 REG_SERROR................................................ 32 6.1.2 REG_IERROR................................................ 32 6.1.3 REG_VERROR................................................ 32 7. No shadow mode..................................................... 32 8. Some examples of typical usage..................................... 33 9. Automatic generation............................................... 36 9.1 shadow_gen control file........................................ 36 9.2 hwregs.h ...................................................... 36


9.3 hwregs.c....................................................... 37 9.4 hwregs_int.h................................................... 37 9.5 hwregs_def.h................................................... 37 10. Integrate the programmer interface into a typical AXIS product.... 37 10.1 Generate the programmer interface files....................... 37 10.2 Customize the programmer interface............................ 37 10.2.1 Register groups.......................................... 37 10.2.2 Default values........................................... 38 10.2.3 Shadow or no shadow mode................................. 38 10.3 Initialization................................................ 38 10.4 Use the programmer interface macros in the code............... 38

1. References

Theese references are Axis internal:
Reference 1: ETRAX100 Hardware System Design Document svinto.hsdd >http://wwwint.axis.se/dept/asic/bin/shli.cgi?k=sv_hsdd< Reference 2: ETRAX100 register description file, text version svinto_regs.axw >http://wwwint.axis.se/dept/asic/bin/shli.cgi?k=sv_regs< Reference 3: Shadow_gen program http://wwwint.axis.se/n/asic/bin/shadow_gen Reference 4: ETRAX100 control file to shadow_gen program http://wwwint.axis.se/n/asic/projects/svinto/include/hwregs.ctrl Reference 5: ETRAX100 register description file, source version http://wwwint.axis.se/n/asic/projects/svinto/doc/work/svinto_regs.rd

2. Introduction

The programmer interface macros described here are intended for programs written in C or C++. They provide an uniform interface to all registers and shadow registers where needed. The programmer interface macros do as much checking as possible at compile time. As an option there is also a debug-mode doing extra runtime checks. Some of the functionality is also available from assembler code. Normally there is little need for shadow registers in system initialization code written in assembler. Once the system memory is initialized the shadow registers are operational. To make the programmer interface macros easier to use and keep up to date they are automatically generated from a register description (ref 5) and a control file (ref 4) by the shadow_gen program (ref 3). This document is written with ETRAX100 in mind, but apply equally well to all AXIS chips in the ETRAX100 series of 'High-Performance Ethernet Peripheral Controllers'.

2.1 Purpose of shadow registers

The real hardware registers in ETRAX100 can be divided in four types: - Read only registers (R) A read only register is a register that can be read but not written to. Writing to a read only register has no direct effect on the register contents, and in some cases may even destroy the contents of other registers. An example of a read only register is R_BUS_STATUS (see ref 2). For read only registers the programmer interface macros should generate compile time errors or warnings if the programmer attempts to write a read only register. - Write only registers (W) A write only register is a register that can be written to, but the written value can not be read back. Reading a write only register result in an undefined value, and in some cases may even result in the contents of another register. An example of a write only register is R_BUS_CONFIG (see ref 2). Note that R_BUS_CONFIG has the same address as R_BUS_STATUS.


For write only registers the programmer interface macros should provide some mechanism to remember the written value and return that when the write only register is read, i.e. a shadow. The first access to a write only register must be a write access to initialize the shadow. - Read/Write registers (RW) A read/write register is a register that can be written to, and the written value can be read back. The fact that the hardware can change the register contents as well distinguish a read/write register from a C variable. For read/write registers the programmer interface macros are not needed, but they are still preferable to give a uniform programmer interface. - Set/Clear registers In ETRAX100 set/clear registers appear in pairs, one set-register and one clear-register, and are a special kind of write only registers. Associated with a pair of set/clear registers is a non accessible internal register. Writing to a set register sets the same bits in the internal register as are set in the write value. Bits not set in the write value keep their value in the internal register. Writing to a clear register clears the same bits in the internal register as are set(!) in the write value. Bits not set in the write value keep their value in the internal register. In pseudo C code: int internal; /* The non accessible internal register. */ internal |= set_value; /* *R_SET = set_value; */ internal &= ~clr_value; /* *R_CLR = clear_value; */ In ETRAX100 the following registers are set/clear registers: R_IRQ_MASK0_SET / R_IRQ_MASK0_CLR R_IRQ_MASK1_SET / R_IRQ_MASK1_CLR R_IRQ_MASK2_SET / R_IRQ_MASK2_CLR R_VECT_MASK_SET / R_VECT_MASK_CLR Similar to the combined set/clear registers are clear registers, R_DMA_CH0_CLR_INTR R_DMA_CH1_CLR_INTR R_DMA_CH2_CLR_INTR R_DMA_CH3_CLR_INTR R_DMA_CH4_CLR_INTR R_DMA_CH5_CLR_INTR R_DMA_CH6_CLR_INTR R_DMA_CH7_CLR_INTR R_DMA_CH8_CLR_INTR R_DMA_CH9_CLR_INTR and set register, R_SET_EOP Since there is nothing in the register description that say which registers are set/clear registers, shadow_gen will by default treat these registers as all other write only registers. A better choice is to ignore the shadow register contents when updating the real register. See the section 'Automatic generation' how to change this.

2.2 Multiple interfaces of the same type

Several of the peripheral interfaces in ETRAX100 are available in multiple instances. To make it possible to write parameterized code, some of the macros take an interface number as a parameter. An example of multiple instances of the same interface are serial port 0 to serial port 3. The interface number is relative to the first interface, e.g. serial port 0.

3. Interface

The programmer interface macros are used to access ETRAX100 registers. Each register is divided into one or more fields, and these fields can hold some value. The macros either operate on one field at a time or on the compete register. There are macros to read, write, or compare fields, to check if values are valid for a particular register and field. There are also macros to read and write to a complete register, to create masks and constants for a complete register. Since the macros operate on one or all fields at a time it sometimes is necessary to do a series of field operations on a variable and only access the register once. Therefore there are macros that operate on an integer variable instead of the real register. It's also possible to get the address of a register and the least significant bit of a register field.

3.1 Common macro parameters

Most of the macros use all or some of the following parameters.

3.1.1 i (interface number)

The interface number is used to write parameterized code for interfaces that are available in more than one instance. The interface number is relative to the 'first' interface, which always is interface number 0. For example there are four equivalent serial ports in ETRAX100, serial port 0, 1, 2, and 3. To access the registers used by serial port 2, use 2 as interface number. In debug mode the interface number is checked. If an error is found at compile time the following warning is seen: warning: right shift count >= width of type I If and error is found at run time the REG_IERROR() macro is called.

3.1.2 reg (register name)

The register name is the name of the register on which the macro will operate. Register names are defined in reference 2. Examples of register names are R_WAITSTATES, R_PAR0_CTRL_DATA, and R_ATA_CTRL_DATA.

3.1.3 field (register field name)

The register field name is a name for a part of a register. Field names are defined in reference 2. Reserved fields are not valid. Examples of field names for register R_WAITSTATES are pcs4_7_zw, pcs4_7_ew, and pcs4_7_lw.


3.1.4 val (value)

A value is something to write to or compare with a field. Valid values for the different register fields are defined in reference 2. The value can be either symbolic or non symbolic. A non symbolic value is an integer value that is within the allowed range for the field. For example in register R_DRAM_CONFIG the allowed range for field group_sel is 9-29. Note that not all possible values are allowed. If no range is specified in the register description file, the valid range is assumed to be 0 : (2^field_width - 1). A symbolic value is something that get an integer value when concatenated by the register and field names by the programmer interface macros. Examples of valid symbolic values for the group_sel field in R_DRAM_CONFIG are grp0 and grp1. If a register field has both symbolic and non symbolic values the programmer interface macros will only work with symbolic values. To use non symbolic values the REG_SET_VAL macro has to be used. In debug mode the value parameter is checked. If a non symbolic value is out of range and it is found at compile time the following warning is seen: warning: left shift count >= width of type If an error is found at run time the REG_VERROR() is called.

3.1.5 var (variable name)

Some of the programmer interface macros don't operate on the specified register but on an integer variable. The var parameter is the variable to use in place of the specified register. Valid field names, symbolic values, and value ranges are relative to the specified register name parameter.

3.2 Definitions

In the following description of the programmer interface macros the following terms will be used.

3.2.1 field width

The width of a register field in nr of bits, where the smallest width is one (1) bit, the widest is 32 bits, and a byte is 8 bits. A field that has field_width bits can assume values in the range 0 : (2^field_width - 1).

3.2.2 register width

The width of a complete register in nr of bits.

3.2.3 return value

The value a macro will expand to.

3.2.4 LSB

Least Significant Bit.


3.2.5 Register group

A register group is a set of registers. Register groups are defined in reference 2, where each chapter is a register group with almost the same name as the chapter. Characters not allowed in C is replaced with an '_'.


3.3 REG_GET Read a field in a register

#define REG_GET( reg, field ) - reg A register name defined in reference 2. - field A valid field name for the above register. - return value An integer value in the range 0 : (2^field_width - 1) - description The REG_GET macro read a field in a register, and shift the read value right so that the LSB of the field is shifted down to bit nr 0. For read write and read only registers the real register is read, and for write only registers the shadow register is read. The register and field names are checked at compile time.


3.4 REG_IGET Read a field in a register

#define REG_IGET( i, reg, field ) - i Interface number. - reg A register name defined in reference 2. - field A valid field name for the above register. - return value An integer value in the range 0 : (2^field_width - 1) - description The REG_IGET macro read a field in a register, and shift the read value right so that the LSB of the field is shifted down to bit nr 0. For read write and read only registers the real register is read, and for write only registers the shadow register is read. The i (interface number) parameter make it possible to write parameterized code which at runtime, select one of several equivalent registers. The register and field names are checked at compile time, and the interface number at run time. This is the same macro as REG_GET but with the additional possibility to select at run time which of several equivalent registers to read.


3.5 REG_VGET Read a field in a variable

#define REG_VGET( reg, field, var ) - reg A register name defined in reference 2. - field A valid field name for the above register. - var An integer variable (or value) to read from in place of the register. - return value An integer value in the range 0 : (2^field_width - 1) - description The REG_VGET macro read a field in an integer variable (or value), and shift the read value right so that the LSB of the field is shifted down to bit nr 0. For all types of registers the variable (or value) is read and the register is only used to define available fields. The register and field names are checked at compile time. This macro can be used when it's desirable to only read the real register once and still be able to access the contents several times.


3.6 REG_SET Write a field in a register.

#define REG_SET( reg, field, val ) - reg A register name defined in reference 2. - field A valid field name for the above register. - val A valid symbolic value or an integer value within the valid range to write to the above field. Valid symbolic values and ranges are defined in reference 2. Note that only values defined in reference 2 are allowed to use. For example the dma_burst field in R_BUS_CONFIG has two valid values, burst16 and burst32. These are the only valid values. I.e. the integer values 0 and 1 are invalid. A few fields have both symbolic and non symbolic values defined. For those fields the REG_SET macro will only allow the symbolic values, and report errors for integer values. To write non symbolic values to a field with symbolic values defined use the REG_SET_VAL macro. - return value The integer value written to the complete register in the range 0 : (2^register_width - 1) - description The REG_SET macro writes a symbolic or non symbolic value to a field in a register. The value is shifted left so that the LSB of the value match the LSB of the specified field. The shifted value is then combined with the current value of the register and written back to the register. For read write registers the current value is read back from the register, and for write only registers the current value is read from the shadow register. This macro isn't defined for read only registers. When writing to a write only register the same value is also written to the shadow register. The register and field names are checked at compile time.


3.7 REG_ISET Write a field in a register.

#define REG_ISET( i, reg, field, val ) - i Interface number. - reg A register name defined in reference 2. - field A valid field name for the above register. - val A valid symbolic value or an integer value within the valid range to write to the above field. Valid symbolic values and ranges are defined in reference 2. Note that only values defined in reference 2 are allowed to use. For example the dma_burst field in R_BUS_CONFIG has two valid values, burst16 and burst32. These are the only valid values. I.e. the integer values 0 and 1 are invalid. A few fields have both symbolic and non symbolic values defined. For those fields the REG_ISET macro will only allow the symbolic values, and report errors for integer values. To write non symbolic values to a field with symbolic values defined use the REG_SET_VAL macro. - return value The integer value written to the complete register in the range 0 : (2^register_width - 1) - description The REG_ISET macro writes a symbolic or non symbolic value to a field in a register. The value is shifted left so that the LSB of the value match the LSB of the specified field. The shifted value is then combined with the current value of the register and written back to the register. For read write registers the current value is read back from the register, and for write only registers the current value is read from the shadow register. This macro isn't defined for read only registers. When writing to a write only register the same value is also written to the shadow register. The i (interface number) parameter make it possible to write parameterized code, which at runtime select one of several equivalent registers. The register and field names are checked at compile time, and the interface number at run time. This is the same macro as REG_SET but with the additional possibility to select at run time which of several equivalent registers to write to.


3.8 REG_VSET Write a field in a variable

#define REG_VSET( reg, field, val, var ) - reg A register name defined in reference 2. - field A valid field name for the above register. - val A valid symbolic value or an integer value within the valid range to write to the above field. Valid symbolic values and ranges are defined in reference 2. Note that only values defined in reference 2 are allowed to use. For example the dma_burst field in R_BUS_CONFIG has two valid values, burst16 and burst32. These are the only valid values. I.e. the integer values 0 and 1 are invalid. A few fields have both symbolic and non symbolic values defined. For those fields the REG_VSET macro will only allow the symbolic values, and report errors for integer values. To write non symbolic values to a field with symbolic values defined use the REG_SET_VAL macro. - var A variable to write to in place of the real register. - return value The integer value written to the var variable in the range 0 : (2^register_width - 1) - description The REG_VSET macro writes a symbolic or non symbolic value to a field in a variable. The value is shifted left so that the LSB of the value match the LSB of the specified field. The shifted value is then combined with the current value of the variable and written back to the variable. This macro isn't defined for read only registers. The register and field names are checked at compile time. This macro can be used when it's desirable to write to several fields in a register but to only write once to the real register.


3.9 REG_SET_VAL Write an integer value to a symbolic field

#define REG_SET_VAL( reg, field, val ) - reg A register name defined in reference 2. - field A valid field name for the above register. - val An integer value within the valid range to write to the above field. Valid ranges are defined in reference 2. - return The integer value written to the complete register in the range 0 : (2^register_width - 1) - description The REG_SET_VAL macro writes a non symbolic value to a field in a register. The value is shifted left so that the LSB of the value match the LSB of the specified field. The shifted value is then combined with the current value of the register and written back to the register. For read write registers the current value is read back from the register, and for write only registers the current value is read from the shadow register. This macro isn't defined for read only registers. When writing to a write only register the same value is also written to the shadow register. The register and field names are checked at compile time. This macro can be used to write non symbolic values to fields that have symbolic values defined. By default the REG_SET, REG_ISET, and REG_VSET macros will require symbolic values for those kind of register fields.


3.10 REG_SET__register-name Write to all fields at one time

#define REG_SET__register-name( f1, v1, f2, v2, .... , fn, vn ) - f1, f2, .. , fn Valid field names for register <register-name>. Order of fields specified in the register description file, see reference 2. First described field <=> f1, last described field <=> fn. Reserved fields shall be skipped. - v1, v2, ... , vn Valid symbolic values or integer values within the valid range to write to the above fields. Valid symbolic values and ranges are defined in reference 2. Note that only values defined in reference 2 are allowed to use. For example the dma_burst field in R_BUS_CONFIG has two valid values, burst16 and burst32. These are the only valid values. I.e. the integer values 0 and 1 are invalid. A few fields have both symbolic and non symbolic values defined. For those fields the REG_SET__register-name macro will only allow the symbolic values, and report errors for integer values. - return The integer value written to <register-name> in the range 0 : (2^register_width - 1) - description The REG_SET__register-name macro writes a combination of symbolic and non symbolic values to all fields in a register at the same time. This macro isn't defined for read only registers. When writing to a write only register the same value is also written to the shadow register. The field names are checked at compile time. This macro can be used to initiate the complete register and the corresponding shadow register.


3.11 REG_SET__register-name__SHADOW Write to all fields at once

#define REG_SET__register-name__SHADOW( f1, v1, f2, v2, .... , fn, vn ) - f1, f2, .. , fn Valid field names for register <register-name>. Order of fields specified in the register description file, see reference 2. First described field <=> f1, last described field <=> fn. Reserved fields shall be skipped. - v1, v2, ... , vn Valid symbolic values or integer values within the valid range to write to the above field. Valid symbolic values and ranges are defined in reference 2. Note that only values defined in reference 2 are allowed to use. For example the dma_burst field in R_BUS_CONFIG has two valid values, burst16 and burst32. These are the only valid values. I.e. the integer values 0 and 1 are invalid. A few fields have both symbolic and non symbolic values defined. For those fields the REG_SET__register-name__SHADOW macro will only allow the symbolic values, and report errors for integer values. - return The integer value written to <register-name> in the range 0 : (2^register_width - 1) - description The REG_SET__register-name macro writes a combination of symbolic and non symbolic values to all fields in a shadow register at the same time. The real register is not updated. This macro isn't defined for read write and read only registers. The field names are checked at compile time. In some rare cases it's necessary to write to a register before the shadow register storage space is available. If it's still desirable to shadow those registers, this macro makes it possible to initialize the shadow register separately at a later time, when the shadow register space is available. Since this macro only write to the shadow register, not to the real register, it's dangerous to use. Only use this macro if you _have_ to!


3.12 REG_MASK__register-name Create a mask

#define REG_MASK__register-name( f1, v1, f2, v2, .... , fn, vn ) - f1, f2, .. , fn Valid field names for register <register-name>. Order of fields specified in the register description file, see reference 2. First described field <=> f1, last described field <=> fn. Reserved fields shall be skipped. - v1, v2, ... , vn on or off. Should field n be in the mask or not. on: Set '1' in all bits in field n. off: Set '0' in all bits in field n. - return The created mask in the range 0 : (2^register_width - 1) - description The REG_MASK__register-name macro create a mask matching one or several fields in a register. This macro can be used to compare several fields in a register with a value created by the REG_VAL__register-name macro in the next section. Also see example 5 in section 6. Some examples of typical usage.


3.13 REG_VAL__register-name Create an integer value

#define REG_VAL__register-name( f1, v1, f2, v2, .... , fn, vn ) - f1, f2, .. , fn Valid field names for register <register-name>. Order of fields specified in the register description file, see reference 2. First described field <=> f1, last described field <=> fn. Reserved fields shall be skipped. - v1, v2, ... , vn Valid symbolic values or integer values within the valid range to set in the above fields in the created integer value. Valid symbolic values and ranges are defined in reference 2. Note that only values defined in reference 2 are allowed to use. For example the dma_burst field in R_BUS_CONFIG has two valid values, burst16 and burst32. These are the only valid values. I.e. the integer values 0 and 1 are invalid. A few fields have both symbolic and non symbolic values defined. For those fields the REG_VAL__register-name macro will only allow the symbolic values, and report errors for integer values. - return The created integer value in the range 0 : (2^register_width - 1) - description The REG_VAL__register-name macro create an integer value matching the complete register. This macro can be used create a value to compare with several fields in a register. To select which fields to compare a mask created by the REG_MASK__register-name macro in the previous section can be used. Also see example 5 in section 6. Some examples of typical usage.


3.14 REG_EQL Compare a field in a register

#define REG_EQL( reg, field, val ) - reg A register name defined in reference 2. - field A valid field name for the above register. - val A valid symbolic value or an integer value within the valid range to compare with the above field. Valid symbolic values and ranges are defined in reference 2. Note that only values defined in reference 2 are allowed to use. For example the dma_burst field in R_BUS_CONFIG has two valid values, burst16 and burst32. These are the only valid values. I.e. the integer values 0 and 1 are invalid. A few fields have both symbolic and non symbolic values defined. For those fields the REG_EQL macro will only allow the symbolic values, and report errors for integer values. - return TRUE if the field value is equal to val parameter. FALSE if the field value is not equal to val parameter. - description The REG_EQL macro read a field in a register, and shift the read value right so that the LSB of the field is shifted down to bit nr 0. The right shifted value is then compared with the val parameter and the result of the comparison is returned. For read write and read only registers the real register is read, and for write only registers the shadow register is read. The register and field names are checked at compile time.


3.15 REG_IEQL Compare a field in a register

#define REG_IEQL( i, reg, field, val ) - i Interface number. - reg A register name defined in reference 2. - field A valid field name for the above register. - val A valid symbolic value or an integer value within the valid range to compare with the above field. Valid symbolic values and ranges are defined in reference 2. Note that only values defined in reference 2 are allowed to use. For example the dma_burst field in R_BUS_CONFIG has two valid values, burst16 and burst32. These are the only valid values. I.e. the integer values 0 and 1 are invalid. A few fields have both symbolic and non symbolic values defined. For those fields the REG_IEQL macro will only allow the symbolic values, and report errors for integer values. - return value TRUE if the field value is equal to val parameter. FALSE if the field value is not equal to val parameter. - description The REG_IEQL macro read a field in a register, and shift the read value right so that the LSB of the field is shifted down to bit nr 0. The right shifted value is then compared with the val parameter and the result of the comparison is returned. For read write and read only registers the real register is read, and for write only registers the shadow register is read. The i (interface number) parameter make it possible to write parameterized code, which at runtime select one of several equivalent registers. The register and field names are checked at compile time, and the interface number at run time. This is the same macro as REG_EQL but with the additional possibility to select at run time which of several equivalent registers to compare with.


3.16 REG_VEQL Compare a field in a variable

#define REG_VEQL( reg, field, val, var ) - reg A register name defined in reference 2. - field A valid field name for the above register. - val A valid symbolic value or an integer value within the valid range to compare with the above field. Valid symbolic values and ranges are defined in reference 2. Note that only values defined in reference 2 are allowed to use. For example the dma_burst field in R_BUS_CONFIG has two valid values, burst16 and burst32. These are the only valid values. I.e. the integer values 0 and 1 are invalid. A few fields have both symbolic and non symbolic values defined. For those fields the REG_VEQL macro will only allow the symbolic values, and report errors for integer values. - var A variable to compare with in place of the real register. - return TRUE if the field value in the variable is equal to val parameter. FALSE if the field value in the variable is not equal to val parameter. - description The REG_VEQL macro read a field in a variable (or value), and shift the read value right so that the LSB of the field is shifted down to bit nr 0. The right shifted value is then compared with the val parameter and the result of the comparison is returned. The register and field names are checked at compile time. This macro can be used when it's desirable to only read the real register once and still be able to compare the contents several times.


3.17 REG_VAL Convert a symbolic value to an integer value

#define REG_VAL( reg, field, val ) - reg A register name defined in reference 2. - field A valid field name for the above register. - val A valid symbolic value for the above field. Valid symbolic values are defined in reference 2. Note that only values defined in reference 2 are allowed to use. For example the dma_burst field in R_BUS_CONFIG has two valid values, burst16 and burst32. These are the only valid values. - return value An integer value corresponding to the val parameter in the range 0 : (2^field_width - 1) - description The REG_VAL macro convert a symbolic value to an integer value at compile time. This macro is necessary since the symbolic values are only defined when combined with the register and field name. The register and field names are checked at compile time.


3.18 REG_CHK_VAL Check an integer value against field range

#define REG_CHK_VAL( reg, field, val ) - reg A register name defined in reference 2. - field A valid field name for the above register. - val An integer value. - return value TRUE if the val parameter is within the valid field range. FALSE if the val parameter is not within the valid field range. - description The REG_CHK_VAL macro check if an integer value is within the valid field range for the specified register field. If no field range is specified in the register description file the range is assumed to be 0 : (2^field_width - 1). The register and field names are checked at compile time. This macro can be used to check if runtime values are valid before writing them to a register field. The other macros only do runtime checks in debug mode, and if they find an error call the REG_VERROR macro.


3.19 REG_RD Read complete register

#define REG_RD( reg ) - reg A register name defined in reference 2. - return value The value read from register reg in the range 0 : (2^register_width - 1) - description The REG_RD macro read the contents of register reg and return it. For read write and read only registers the real register is read, and for write only registers the shadow register is read. The register name is checked at compile time. This macro can be used to read the complete register to a variable for further processing with the REG_Vxyz macros.


3.20 REG_IRD Read complete register

#define REG_IRD( i, reg ) - i Interface number. - reg A register name defined in reference 2. - return value The value read from register reg in the range 0 : (2^register_width - 1) - description The REG_RD macro read the contents of register reg and return it. For read write and read only registers the real register is read, and for write only registers the shadow register is read. The i (interface number) parameter make it possible to write parameterized code which at runtime, select one of several equivalent registers. The register name is checked at compile time, and the interface number at run time. This is the same macro as REG_IRD but with the additional possibility to select at run time which of several equivalent registers to read. This macro can be used to read the complete register to a variable for further processing with the REG_Vxyz macros.


3.21 REG_WR Write complete register

#define REG_WR( reg, var ) - reg A register name defined in reference 2. - var An integer variable (or value) containing the value to be written to the register reg. - return value The value written to register reg in the range 0 : (2^register_width - 1) - description The REG_WR macro writes an integer value to the complete register. This macro isn't defined for read only registers. When writing to a write only register the same value is also written to the shadow register. The register and field names are checked at compile time. There are no checks if the value written to the register is valid. This macro can be used to write a value to a register after the value has been processed by the REG_Vxyz macros.


3.22 REG_IWR Write complete register

#define REG_IWR( i, reg, var ) - i Interface number. - reg A register name defined in reference 2. - var An integer variable (or value) containing the value to be written to the register reg. - return value The value written to register reg in the range 0 : (2^register_width - 1) - description The REG_WR macro writes an integer value to the complete register. This macro isn't defined for read only registers. When writing to a write only register the same value is also written to the shadow register. The i (interface number) parameter make it possible to write parameterized code, which at runtime select one of several equivalent registers. The register name is checked at compile time, and the interface number at run time. There are no checks if the value written to the register is valid. This is the same macro as REG_WR but with the additional possibility to select at run time which of several equivalent registers to write to. This macro can be used to write a value to a register after the value has been processed by the REG_Vxyz macros.


3.23 REG_ADDR Address to a register

#define REG_ADDR( reg ) - reg A register name defined in reference 2. - return value A pointer to the real register. For example (volatile udword*) 0xb0000024 for the R_WATCHDOG register. - description The REG_ADDR macro return the address to the real register making it possible to access the register in ways not supported by the programmer interface. Note that using the pointer to read and write the register bypass the shadow register functionality and all checks done by the other programmer interface macros. Only use this macro if you _have_ to and know what you are doing. The register name is checked at compile time.


3.24 REG_BITNR Least significant bit in a field

#define REG_BITNR( reg, field ) - reg A register name defined in reference 2. - field A valid field name for the above register. - return value The least significant bit (LSB) in the specified register field. - description The REG_BITNR macro return the least significant bit of a register field. The register and field name is checked at compile time.


4. Initialization

Before reading or writing a field in a write only register, the shadow register must be initialized. To do this use the REG_SET_register-name() macro. In debug mode it's verified at runtime that this initialization has been done when a field is accessed. If not the REG_SERROR() macro will be called. It is also possible to initiate the shadow register without writing to the real register with the REG_SET__register-name__SHADOW() macro. This can be used if the register is initiated in assembler code before shadow register storage space is available, and it is a problem writing the same value one more time with the REG_SET_register-name macro. For read write registers there is no shadow register to initialize, but it's still possible to initialize the register with the REG_SET_register-name macro. However, no runtime check in debug mode of the initialization will be done. Read only registers can't be initialized. To make initialization easier the shadow_gen program will generate a template file defining default values for write only registers. It will also declare a function initializing all write only registers with these default values using the SET_REG_register-name macros.

5. Selecting register groups

There are two reasons for not always using all the register groups. In a highly configurable circuit as ETRAX100 one physical register can be used to several functions depending on how the circuit is configured. Depending on this configuration one physical register may have different logical names with different field definitions. But for a typical product only one of these overlapping logical registers are used. Also using the programmer interface has a memory cost because the register shadow and the initiated flag has to be stored. Therefore memory limited products will limit the programmer interface to the used set of registers. All register groups are by default disabled in the hwregs_def.h file. This is done by the shadow_gen program as it defines the USE_GROUP__group-name macros to zero. The preferred way to enable a register group is to define the corresponding USE_GROUP__register-group macro to one in the project.h file, included in hwregs.h.

6. Debug mode

The programmer interface macros always check that register names, field names, and symbolic values are valid. In debug mode the macros also check that the shadow registers are initiated before they are used, that the interface number is within the range of available interfaces, and that non symbolic values are within the valid field range. The action taken when a runtime error is found is defined by the REG_SERROR, REG_IERROR, and REG_VERROR macros. The extra checks in debug mode are if possible done at compile time but if not at run time. The check that the shadow registers are initiated require an extra flag variable for each register. Therefor the debug mode will give less performance and larger code. Debug mode is by default controlled by the DEBUG macro defined in debug.h, but it's possible to override this default by defining the REG_DEBUG macro to zero (off) or one (on) before including hwregs.h.


6.1 User defined error action

The action taken when a run time error is detected is defined by the REG_SERROR, REG_IERROR, and REG_VERROR macros. It's up to the user to defined what these macros will do.

6.1.1 REG_SERROR

#define REG_SERROR()

6.1.2 REG_IERROR

#define REG_IERROR()

6.1.3 REG_VERROR

#define REG_VERROR()

7. No shadow mode

For some very memory limited products, e.g. the initial boot strap loader which is limited to one ethernet packet, it's possible to use the programmer interface without shadow registers and without the initiated flags. This mode is enebled by defining the REG_NO_SHADOW macro. In no shadow mode the programmer interface will not declare any shadow register or initiated flag storage space. Since there are no shadow registers or initiated flags the programmer interface will work as if the shadow always is zero and as if all registers has been initialized. The REG_NO_SHADOW macro control the storage space used by the programmer interface and the DEBUG macro control how much checking is done at runtime.


8. Some examples of typical usage

Ex 1: Wait for next character on serial port. /* * Must only read R_SERIAL0_READ once, * otherwise data and data_avail may be inconsistent. * * 1. Read complete register and save contents in variable 'read'. * 2. Test data_avail bit in variable 'read'. * 3. If data is available read data_in field in variable 'read'. */ while( REG_VEQL( R_SERIAL0_READ, data_avail, no, /* 2. */ (read = REG_RD(R_SERIAL0_READ)) ) /* 1. */ { ; /* No char avail, try again. */ } ch = REG_VGET( R_SERIAL0_READ, data_in, read ); /* 3. */ Ex 2: Set transmit and receive baud rates. int recBaud; /* Set transmit baud rate on TX0 to 300 baud. */ REG_SET( R_SERIAL0_BAUD, tr_baud, c300Hz ); /* Set same baud rate on RX0 as is set on TX0. */ /* Must use the REG_SET_VAL macro since the rec_baud */ /* field only has symbolic values defined. */ recBaud = REG_GET( R_SERIAL0_BAUD, tr_baud ); REG_SET_VAL( R_SERIAL0_BAUD, rec_baud, recBaud );


/* Same as previous but without the REG_SET_VAL macro. */ /* The REG_VAL macro is used to convert the symbolic */ /* baud rate value to an integer value. */ recBaud = REG_GET( R_SERIAL0_BAUD, tr_baud ); switch( recBaud ){ case REG_VAL( R_SERIAL0_BAUD, tr_baud, c300Hz ): REG_SET( R_SERIAL0_BAUD, tr_baud, c300Hz ); break; case REG_VAL( R_SERIAL0_BAUD, tr_baud, c600Hz ): REG_SET( R_SERIAL0_BAUD, tr_baud, c600Hz ); break; case REG_VAL( R_SERIAL0_BAUD, tr_baud, c1200Hz ): REG_SET( R_SERIAL0_BAUD, tr_baud, c1200Hz ); break; case REG_VAL( R_SERIAL0_BAUD, tr_baud, c2400Hz ): REG_SET( R_SERIAL0_BAUD, tr_baud, c2400Hz ); break; case REG_VAL( R_SERIAL0_BAUD, tr_baud, c4800Hz ): REG_SET( R_SERIAL0_BAUD, tr_baud, c4800Hz ); break; case REG_VAL( R_SERIAL0_BAUD, tr_baud, c9600Hz ): REG_SET( R_SERIAL0_BAUD, tr_baud, c9600Hz ); break; case REG_VAL( R_SERIAL0_BAUD, tr_baud, c19k2Hz ): REG_SET( R_SERIAL0_BAUD, tr_baud, c19k2Hz ); break; case REG_VAL( R_SERIAL0_BAUD, tr_baud, c38k4Hz ): REG_SET( R_SERIAL0_BAUD, tr_baud, c34k8Hz ); break; case REG_VAL( R_SERIAL0_BAUD, tr_baud, c57k6Hz ): REG_SET( R_SERIAL0_BAUD, tr_baud, c57k6Hz ); break; case REG_VAL( R_SERIAL0_BAUD, tr_baud, c115k2Hz ): REG_SET( R_SERIAL0_BAUD, tr_baud, c115k2Hz ); break; case REG_VAL( R_SERIAL0_BAUD, tr_baud, c230k4Hz ): REG_SET( R_SERIAL0_BAUD, tr_baud, c230k4Hz ); break; case REG_VAL( R_SERIAL0_BAUD, tr_baud, c460k8Hz ): REG_SET( R_SERIAL0_BAUD, tr_baud, c460k8Hz ); break; case REG_VAL( R_SERIAL0_BAUD, tr_baud, c921k6Hz ): REG_SET( R_SERIAL0_BAUD, tr_baud, c921k6Hz ); break; case REG_VAL( R_SERIAL0_BAUD, tr_baud, c1843k2Hz ): REG_SET( R_SERIAL0_BAUD, tr_baud, c1843k2Hz ); break; case REG_VAL( R_SERIAL0_BAUD, tr_baud, c6250kHz ): REG_SET( R_SERIAL0_BAUD, tr_baud, c6250Hz ); break; case REG_VAL( R_SERIAL0_BAUD, tr_baud, reserved ): REG_SET( R_SERIAL0_BAUD, tr_baud, reserved ); break; default: /* This should never happen */ } Ex 3: Verify parameter value. int recBaud; do { recBaud = ask_user_for_baud_rate(); while( ! REG_CHK_VAL( R_SERIAL0_BAUD, tr_baud, recBaud ) ); REG_SET_VAL( R_SERIAL0_BAUD, tr_baud, recBaud ); Ex 4: Set RX baud rate on all serial ports in ETRAX100 (0, 1, 2, 3). int serial_port_nr; /* Interface number. */ for( serial_port_nr = 0; serial_port_nr < 4; serial_port_nr++ ) { REG_ISET( serial_port_nr, R_SERIAL0_BAUD, rec_baud, c300Hz ); }
Ex 5: Comparing several fields in a register at one time int check_par_status( int port_nr, int mask, int exp_stat ) { return( REG_IRD(port_nr, R_PAR0_STATUS_DATA) & mask == mask & exp_stat ); } int busy_mask, fault_mask; int busy_fault_active, fault_active; /* Create a mask matching the interesting fields. */ busy_fault_mask = REG_MASK__R_PAR0_STATUS_DATA( mode, off, perr, off, ack, off, busy, on, /* Only interested in the busy */ fault, on, /* and fault fields. */ sel, off, tr_rdy, off, dav, off, ecp_cmd, off, data, off ); /* Create a value to compare fields with. */ busy_fault_active = REG_VAL__R_PAR0_STATUS_DATA( mode, manual, /* Don't Care */ perr, active, /* Don't Care */ ack, active, /* Don't Care */ busy, active, fault, active, sel, active, /* Don't Care */ tr_rdy, busy, /* Don't Care */ dav, nodata, /* Don't Care */ ecp_cmd, data, /* Don't Care */ data, 0x00 /* Don't Care */ ); /* Create another value to compare fields with. */ fault_active = REG_VAL__R_PAR0_STATUS_DATA( mode, manual, /* Don't Care */ perr, active, /* Don't Care */ ack, active, /* Don't Care */ busy, inactive, fault, active, sel, active, /* Don't Care */ tr_rdy, busy, /* Don't Care */ dav, nodata, /* Don't Care */ ecp_cmd, data, /* Don't Care */ data, 0x00 /* Don't Care */ ); /* Test parallel port 0 status. */ if( check_par_status( 0, busy_fault_mask, busy_fault_active ) ) { /* busy and fault are active */ } else if ( check_par_status( 0, busy_fault_mask, fault_active ) ) { /* busy is inactive and fault is active */ }

9. Automatic generation

The shadow_gen program read a register description file, and optionally a control file specifying which registers should have shadow registers, and automatically generates hwregs.h, hwregs.c, hwregs_int.h, and hwregs_def.h. For ETRAX100 these files are available in /n/asic/projects/svinto/include/

9.1 shadow_gen control file

The shadow_gen control file gives limited possibility to control how shadow_gen generate the programmer interface. See reference 4 for the ETRAX100 control file. There are two ways to control the generation. First you can add #defines to the hwregs_int.h file. The following line in the control file will add three new #defines in the hwregs_int.h file. R_DMA_CH0_BUF: FIRST=0 LAST=9 OFFSET=16 /* From control-file 'hwregs.ctrl' */ #define R_DMA_CH0_BUF__FIRST 0 #define R_DMA_CH0_BUF__LAST 9 #define R_DMA_CH0_BUF__OFFSET 16 /* end */ Secondly, since the control file is passed through a PERL pre processor you have access to all global data in the shadow_gen script. The PERL pre processor evaluates all lines starting with #. as PERL code. For example the following line override the register type for R_IRQ_MASK0_CLR to be a read write register instead of a write only register as stated in the register description file. #. $reg->{R_IRQ_MASK0_CLR}->{type} = "RW"; To make the programmer interface macros ignore the contents of a shadow register when reading it, and use zero instead, use the following in the control file. #. $reg->{R_SET_EOP}->{zero_shadow} = "yes"; To calculate the address offset between the registers for two external DMA channels the following line is used, #. $offset = $reg->{R_EXT_DMA_1_CMD}->{addr} - #. $reg->{R_EXT_DMA_0_CMD}->{addr}; and then the calculated value ($offset) can be used to create #defines in the hwregs_int.h file according to the first control alternative. R_EXT_DMA_0_STAT: FIRST=0 LAST=1 OFFSET=$offset

9.2 hwregs.h

hwregs.h defines the user interface, see section 3. It is this file that should be included to use the programmer interface.


9.3 hwregs.c

hwregs.c declares the shadow register storage space, the shadow_init__hwregs() function, and in debug mode the extra flags needed to check that the shadow registers are initiated before they are used.

9.4 hwregs_int.h

hwregs_int.h is the internal implementation of the shadow register functionality. Macros in this file is not intended for the user of the programmer interface. Do not include this file in your program, it's done by hwregs.h

9.5 hwregs_def.h

hwregs_def.h is a template file defining default values for all fields in all registers. These default values are then used by the init_shadow__hwregs() function to initiate all write only registers. Do not include this file in your program it's done by hwregs.h.

10. Integrate the programmer interface into a typical AXIS product

The following assume you are using the programmer interface in a typical AXIS product.

10.1 Generate the programmer interface files

Use shadow_gen (ref 3) to generate the hwregs.h, hwregs.c, hwregs_int.h, and hwregs_def.h files. Then copy them to an appropriate place in the code tree, and make your make utility aware of them.

10.2 Customize the programmer interface

The things possible to customize are which register groups should be enabled, the default shadow register contents for the write-only registers in these groups, and if to use shadow registers or not.

10.2.1 Register groups

The register groups are enabled by defining the corresponding USE_GROUP__group-name to one. Note that you should not enable more than one register group that share the same physical registers.


10.2.2 Default values

The default values are specified by defining the register-name__field-name__DEFAULT macros. Note that you _must_ define default values for all fields in all register that is enabled by the USE_GROUP__group-name macros. This can be done at two places. - hwregs_def.h Here you typically define 'default-default' values that apply in most products. - project.h Here you typically define product specific default values.

10.2.3 Shadow or no shadow mode

By default the shadow registers are enabled, but for very memory limited products you can define the REG_NO_SHADOW macro to enable the no shadow mode, see section 7.

10.3 Initialization

Before the programmer interface can be used in the code the init_shadow__hwregs() function has to be called to initialize the shadow registers.

10.4 Use the programmer interface macros in the code

To use the programmer interface macros in the code include the hwregs.h file, and _only_ the hwregs.h file, and the macros defined in this document are available. And don't forget to compile and link with hwregs.c. Debug mode is controlled by the DEBUG macro in debug.h, or by locally defining REG_DEBUG before hwregs.h is included.