The functions given below have so far been implemented as VHDL modules (see flinkVHDL). For all of them a suitable driver is available in the flink Userspace Library and the flinkLite Library.
function id | name | description |
---|---|---|
0x00 | Info | info subdevice with description |
0x01 | AnalogIn | analog input, ADC |
0x02 | AnalogOut | analog output, DAC |
0x05 | DigitalIO | digital input and output, GPIO |
0x06 | Counter | counter |
0x0c | PWM | pulse width modulated output |
0x0d | PPWA | period and pulse width measurement |
0x0f | UART | serial communication |
0x10 | Watchdog | watchdog timer |
0x11 | Sensor | various sensors (photo, inductive, acceleration) |
0x15 | Stepper Motor | stepper motor driver |
0x18 | IRQ Muliplexer | multiplexer for interrupt lines |
As described in flink, Universal Serial Interface to FPGA's every subdevice realizes a certain function. The function id together with status and configuration registers can be found in the header and subheader section. Every subdevice has further registers which are specific for a certain function. These registers are described below for the available functions.
This subdevice might be present or not in a device. Its purpose is to indicate the total memory size of the whole device. It further has a 28 bytes description field. This allows for identifying a given design.
Offset | Size [byte] | Name | r/w | Const | Description |
---|---|---|---|---|---|
0x20 | 4 | memory size | r | yes | total memory size for the device (in bytes) including all subdevices |
0x24 | 28 | description | r | yes | contains a description, including a name and/or a date |
Insert the description in hexadecimal notation, e.g. “ABC” becomes #414243. Enter in the description field with left alingment, e.g. 41424300000000000000000000000000000000000000000000000000 . Use a string to hex converter. The status and configuration registers in the subheader are unused with this function.
This function is used to gather analog input data from an ADC. The ADC is connected through SPI. Make sure to set the base clock of this subdevice correctly (in Altera or Vivado), because the serial clock is derived from that clock.
Offset | Size [byte] | Name | r/w | Const | Description |
---|---|---|---|---|---|
0x20 | 4 | resolution | r | yes | this is the number of resolvable digital steps |
0x24 | 4 | value_0 | r | no | channel 0: digitized input value |
0x28 | 4 | value_1 | r | no | channel 1: digitized input value |
.. | 4 | .. | r/w | no | .. |
The status register in the subheader is unused with this function. In the configuration register setting the bit 0 will reset the subdevice. This subdevice uses 3 to 4 pins for the SPI depending on the particular type.
Currently there are three subtypes of this subdevice. The subtype information can be found in the function
register of the header.
Subtype ID | Description | Example |
---|---|---|
0x1 | Simple ADC with continuous sampling | ADC128S102 |
0x2 | Advanced model with integrated filter and sampling mode selection | AD7606 |
0x3 | Simple ADC, low power | AD7476 |
This function serves to drive an DAC. The DAC is connected through SPI. Make sure to set the base clock of this subdevice correctly (in Altera or Vivado), because the serial clock is derived from that clock.
Offset | Size [byte] | Name | r/w | Const | Description |
---|---|---|---|---|---|
0x20 | 4 | resolution | r | yes | this is the number of resolvable digital steps |
0x24 | 4 | value_0 | r/w | no | channel 0: digital output value |
0x28 | 4 | value_1 | r/w | no | channel 1: digital output value |
.. | 4 | .. | r/w | no | .. |
The status register in the subheader is unused with this function. In the configuration register setting the bit 0 will reset the subdevice. This subdevice uses 5 pins.
Currently there is one subtype of this subdevice. The subtype information can be found in the function
register of the header.
Subtype ID | Description | Example |
---|---|---|
0x1 | Simple DAC where the outputs are continuously set. All channels are updated at the same time | AD5668 |
0x2 | Simple DAC where the outputs are continuously set. All channels are individually updated, +-10V | AD5754 |
This function realizes digital inputs and outputs. Make sure to set the base clock of this subdevice correctly (in Altera or Vivado), because debouncing is derived from that clock.
Offset | Size [byte] | Name | r/w | Const | Description |
---|---|---|---|---|---|
0x20 | 4 | base_clk | r | yes | base clock in Hz |
0x24 | 4 | dir_0 | r/w | no | direction bits for channels 0 .. 31 |
0x28 | 4 | dir_1 | r/w | no | direction bits for channels 32 .. 63 |
.. | 4 | .. | r/w | no | .. |
0xyy | 4 | val_0 | r/w | no | digital value for channels 0 .. 31 |
0xyy+4 | 4 | val_1 | r/w | no | digital value for channels 32 .. 63 |
.. | 4 | .. | r/w | no | .. |
0xzz | 4 | irq_debounce_0 | r/w | no | IRQ debounce time for channel 0 (multiple of base_clk) |
0xzz+4 | 4 | irq_debounce_1 | r/w | no | IRQ debounce time for channel 1 (multiple of base_clk) |
.. | 4 | .. | r/w | no | .. |
A value of '1' configures a pin as an output in the direction register.
The status register in the subheader is unused with this function. In the configuration register setting the bit 0 will reset the subdevice.
At powerup all pins will be inputs. This subdevice uses a pin on the FPGA device for each channel.
All modules which count something can implement this interface. An example for this could be a FQD (fast quadrature decoder). It counts the number of edges of a signal. The counter module implements a 16 bit counter, hence, reading the counter value will return only 2 bytes.
Offset | Size [byte] | Name | r/w | Const | Description |
---|---|---|---|---|---|
0x20 | 4 | count_0 | r | no | counter channel 0 |
0x24 | 4 | count_1 | r | no | counter channel 1 |
.. | 4 | .. | r | no | .. |
The status register in the subheader is unused with this function. In the configuration register setting the bit 0 will reset the subdevice. This subdevice uses two pins on the FPGA device for each channel.
Currently there is one subtype of this subdevice. The subtype information can be found in the function
register of the header.
Subtype ID | Description |
---|---|
0x0 | fast quadrature decoder (using signals A and B) |
Used to output pulse with modulated output signals. Make sure to set the base clock of this subdevice correctly (in Altera or Vivado), because the frequency setting is derived from this clock.
Offset | Size [byte] | Name | r/w | Const | Description |
---|---|---|---|---|---|
0x20 | 4 | base_clk | r | yes | base clock in Hz |
0x24 | 4 | ptime_0 | r/w | no | channel 0: period in multiples of base clock |
0x28 | 4 | ptime_1 | r/w | no | channel 1: period in multiples of base clock |
.. | 4 | .. | r/w | no | .. |
0xyy | 4 | htime_0 | r/w | no | channel 0: high time in multiples of base clock |
0xyy+4 | 4 | htime_1 | r/w | no | channel 1: high time in multiples of base clock |
.. | 4 | .. | r/w | no | .. |
The status register in the subheader is unused with this function. In the configuration register setting the bit 0 will reset the subdevice. This subdevice uses a pin on the FPGA device for each channel.
This function realizes period and pulse width measurements. Make sure to set the base clock of this subdevice correctly (in Altera or Vivado), because the time measurement is derived from that clock.
Offset | Size [byte] | Name | r/w | Const | Description |
---|---|---|---|---|---|
0x20 | 4 | base_clk | r | yes | base clock in Hz |
0x24 | 4 | ptime_0 | r | no | channel 0: period in multiples of base clock |
0x28 | 4 | ptime_1 | r | no | channel 1: period in multiples of base clock |
.. | 4 | .. | r | no | .. |
0xyy | 4 | htime_0 | r | no | channel 0: high time in multiples of base clock |
0xyy+4 | 4 | htime_1 | r | no | channel 1: high time in multiples of base clock |
.. | 4 | .. | r | no | .. |
The status register in the subheader is unused with this function. Setting the bit 0 in the configuration register will reset the subdevice. This subdevice uses a pin on the FPGA device for each channel.
This function implements one or more serial communication interfaces. Make sure to set the base clock of this subdevice correctly (in Altera or Vivado), because the baud rate is derived from that clock.
Offset | Size [byte] | Name | r/w | Const | Description |
---|---|---|---|---|---|
0x20 | 4 | base_clk | r | yes | base clock in Hz |
0x24 | 4 | devider_0 | rw | no | uart 0: clock divider for baud rate |
0x28 | 4 | devider_1 | rw | no | uart 1: clock divider for baud rate |
.. | 4 | .. | rw | no | .. |
0xyy | 4 | tx_0 | rw | no | uart 0: transmit register |
0xyy+4 | 4 | tx_1 | rw | no | uart 1: transmit register |
.. | 4 | .. | rw | no | .. |
0xzz | 4 | rx_0 | r | no | uart 0: receive register |
0xzz+4 | 4 | rx_1 | r | no | uart 1: receive register |
.. | 4 | .. | r | no | .. |
0xuu | 4 | stat_0 | r | no | uart 0: status register |
0xuu+4 | 4 | stat_1 | r | no | uart 1: status register |
.. | 4 | .. | r | no | .. |
Both the transmit and receive path contain a 1024 entry FIFO memory.
The devider register will devide the base clock and the resulting frequency is the baudrate of the UART. The status register in the subheader is unused with this function. Setting the bit 0 in the configuration register will reset the subdevice. The status register of each channel contains the following information
31…26 | 25…16 | 15…7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
unused | number of active entries in rx FIFO | unused | tx FIFO full | tx FIFO half full | tx FIFO empty | unused | rx FIFO full | rx FIFO half full | rx FIFO empty |
This subdevice uses a pair of pins (rx / tx) on the FPGA device for each uart (channel).
The watchdog is a decrementing counter which will fire as soon as it reaches 0. The counter decrements with every clock cycle. Is has to be set periodically to a desired value to prevent the watchdog of running out. This preset value determines the watchout time. Make sure to set the base clock of this subdevice correctly (in Altera or Vivado), because the watchdog timer is derived from that clock. The field nofChannels
will return 1.
Offset | Size [byte] | Name | r/w | Const | Description |
---|---|---|---|---|---|
0x20 | 4 | base_clk | r | yes | base clock in Hz |
0x24 | 4 | counter | r/w | no | counter |
The last bit in the status register shows the value of the watchdog signal. If '1': the watchdog-timer is still running and the signal granted
is set. If '0': the watchdog has timed out and granted
is not set.
The last bit in the configuration register holds the rearm bit. When the watchdog has fired (timed out), it has to be reset by setting the rearm bit. Write '1' to rearm. This bit is self clearing to '0'.
counter: set the watchdog timeout before you arm the watchdog.
This subdevice uses two pins on the FPGA device. The two output are as follows
Currently there are two subtypes of this subdevice. The subtype information can be found in the function
register of the header.
ID | Description | Example |
---|---|---|
0x1 | Inductance to digital converter | LDC1000 |
0x2 | Motion tracking sensor | LMPU9250 |
0x3 | Gyroskope | ITG3200 |
0x4 | Reflective Photoelectric Sensor | TCRT1000 |
The status and control register in the subheader are described below.
31 | … | 14 | 13 | 12 | 11 | 10 | 09 | 08 | 07..00 |
OSC_dead | DRDYB | wake_up | comperator | configuring | device_id |
device_id: Revision ID of Silicon.
configuring: '1' indicates that the fpga is writing data to the sensor during this time the data registers are not updated.
comperator: 1:Proximity data is less than Threshold Low value, 0:Proximity data is more than Threshold High value.
wake_up: 1:Wake-up disabled, 0:Wake-up triggered. Proximity data is more than Threshold High value.
DRDYB: 1:No new data available, 0:Data is ready to be read.
OSC_dead: 1:Indicates oscillator overloaded and stopped, 0:Oscillator working.
NOTE: device_id, comperator, wake_up, DRDYB, OSC_dead are directly maped from the sensors status register. Therefore they are not showing the fpgas internal state.
31 | … | 11 | 10..08 | .. | 07..06 | 05..02 | 01 | 00 |
PWD_MODE | intb_mode | .. | amplitude | response_time | update_config | reset |
reset: Resets the functions internal status and reads the actual configuration from the sensor
update_config: If '1' is written the configuration is written to the device. Then the configuration is read from the sensor and the config register inside the FPGA is updated. Writing config data during the configuring bit is set in the status register can lead to invalid behavioral. During this time no new data are sampled. The configuring bit in the status register indicates when the update process is finished. Before updating the configuration the sensor has to be brought into power done mode!
response_time:
000: Reserved, 001: Reserved, 010: 192, 011: 384, 100: 768, 101: 1536, 110: 3072, 111: 6144
amplitude: Sets the oscillation amplitude: 00:1V, 01:2V, 10:4V, 11:Reserved
intb_mode: 000: All modes disabled, 001: Wake-up Enabled on INTB terminal, 010: INTB terminal indicates the status of Comparator output, 100: DRDYB Enabled on INTB terminal
PWD_MODE: 0:Standby mode, 1:Active Mode
The register bank of the LDC1000 is as follows:
Offset | Size [byte] | Name | r/w | Const | Description |
---|---|---|---|---|---|
0x20 | 4 | base_clk | r | yes | base clock in Hz |
0x24 | 4 | tbclk_freq | r/w | no | frequency of the tbclk clk in multibles of base clock |
0x28 | 4 | rp | r/w | no | rp_min and rp_max config register |
0x2C | 4 | min_sens_frequ | r/w | no | min sensor frequency config register |
0x30 | 4 | threshold | r/w | no | threshold high and low config register |
0x34 | 4 | proximity | r | no | proximity data register |
0x38 | 4 | frequ_count | r | no | frequency counter data register |
31 | … | 15..08 | 07..00 |
rp_max | rp_min |
This registers are directly mapped to the sensors registers. See ldc1000 datasheet for more information.
31 | … | 07..00 |
min_sens_frequ |
This register is directly mapped to the sensors register. See ldc1000 datasheet for more information.
31 | … | 15..08 | 07..00 |
threshold_high_msb | threshold_low_msb |
This registers are directly mapped to the sensors registers. See ldc1000 datasheet for more information.
31 | … | 15..00 |
proximity |
This register is directly mapped to the sensors register. See ldc1000 datasheet for more information.
31 | … | 23..00 |
frequ_count |
This register is directly mapped to the sensors register. See ldc1000 datasheet for more information.
The status and control register in the subheader are described below.
31 | … | 05..04 | 03..02 | 01 | 00 |
ACCEL_FS_SEL | GYRO_FS_SEL | configuring | reset |
reset: Resets the internal state and starts a read of the actual sensor config. configuring will go to '1'.
configuring: '1' indicates that the fpga is writing data to the sensor. After the config is writen to the sensor the fpga will read it back and update the fpga internal config register. All changes on the configuration during this time are discarded. A read of the config register during configuring is '1' can end in getting invalid values. Also during this time the data registers are not updated.
all other: All other bits are described in the MPU9250 register map in the manual.
31 | … | 01 | 00 |
update_config | reset |
reset: Resets the functions internal status and reads the actual configuration from the sensor
update_config: If '1' is written the configuration is written to the sensor. During this time no new data are sampled. The configuring bit in the status register indicates when the update process is finished.
The register bank of the LMPU9250 is as follows:
Offset | Size [byte] | Name | r/w | Const | Description |
---|---|---|---|---|---|
0x20 | 4 | acceleration_x_offset | rw | no | x axis acceleration offset |
0x24 | 4 | acceleration_y_offset | rw | no | y axis acceleration offset |
0x28 | 4 | acceleration_z_offset | rw | no | z axis acceleration offset |
0x2C | 4 | gyro_x_offset | rw | no | gyroscope x axis offset |
0x30 | 4 | gyro_y_offset | rw | no | gyroscope y axis offset |
0x34 | 4 | gyro_z_offset | rw | no | gyroscope z axis offset |
0x38 | 4 | acceleration_x | r | no | x axis acceleration data |
0x3C | 4 | acceleration_y | r | no | y axis acceleration data |
0x40 | 4 | acceleration_z | r | no | z axis acceleration data |
0x44 | 4 | gyro_x | r | no | gyroscope x axis data |
0x48 | 4 | gyro_y | r | no | gyroscope y axis data |
0x4C | 4 | gyro_z | r | no | gyroscope z axis data |
0x50 | 4 | mag_x | r | no | magnetometer x axis data |
0x54 | 4 | mag_y | r | no | magnetometer y axis data |
0x58 | 4 | mag_z | r | no | magnetometer z axis data |
For all data registers only the lower 16 bit are valid.
Offset | Size [byte] | Name | r/w | Const | Description |
---|---|---|---|---|---|
0x20 | 4 | gyro_xout_h | r | no | GYRO_XOUT_H of the ITG3200 |
0x24 | 4 | gyro_xout_l | r | no | GYRO_XOUT_L of the ITG3200 |
0x28 | 4 | gyro_yout_h | r | no | GYRO_YOUT_H of the ITG3200 |
0x2C | 4 | gyro_yout_l | r | no | GYRO_YOUT_L of the ITG3200 |
0x30 | 4 | gyro_zout_h | r | no | GYRO_ZOUT_H of the ITG3200 |
0x34 | 4 | gyro_zout_l | r | no | GYRO_ZOUT_L of the ITG3200 |
This function is used to drive reflective photoelectric sensors of type TRCT1000. Please refer to TCRT1000 Module Schema for more information. The subdevice generates a pulse to drive the sensor which is selected through individual signals. Make sure to set the base clock of this subdevice correctly (in Altera or Vivado), because the serial clock is derived from that clock.
Offset | Size [byte] | Name | r/w | Const | Description |
---|---|---|---|---|---|
0x20 | 4 | resolution | r | yes | this is the number of resolvable digital steps |
0x24 | 4 | sensor_0 | r | no | channel 0: digitized input value |
0x28 | 4 | sensor_1 | r | no | channel 1: digitized input value |
.. | 4 | .. | r | no | .. |
0xyy | 4 | irq_level_up_0 | r/w | no | channel 0: interrupt upper level |
0xyy+4 | 4 | irq_level_up_1 | r/w | no | channel 1: interrupt upper level |
.. | 4 | .. | r/w | no | .. |
0xzz | 4 | irq_level_low_0 | r/w | no | channel 0: interrupt lower level |
0xzz+4 | 4 | irq_level_low_0 | r/w | no | channel 1: interrupt lower level |
.. | 4 | .. | r/w | no | .. |
The status register in the subheader is unused with this function. In the configuration register setting the bit 0 will reset the subdevice.
This subdevice uses three pins to connect an ADC7476. Further, the appropriate number of pins for the decoder is number_of_sensors = 2number_of_decoder_pins. The pulse pin has to be connected to the trigger input of the module.
Used to control stepper motors. You can set several configuration parameters (forward, backward, full or half step, two or single phase). When starting a motor its speed will ramp up to a given top speed and ramp down to its final position. When in speed mode, a ramp is used to change from its current speed to the new target speed.
Changes in direction, step type, phase mode and start speed are only taking place when the motor is stopped. Make sure to set the base clock of this subdevice correctly (in Altera or Vivado), because prescalers are derived from that clock.
The motor moves through the specified number of steps. It uses a ramp to accelerate up and down. Changes in the configuration, prescaler and steps registers are only applied when the motor is at standstill. The module automatically resets the start bit in the motor configuration register when done. When the start bit is manually reset, the motor immediately ramps down without reaching the number of steps.
The motor ramps up to a preset speed. When the stop command is issued, the speed ramps down to a standstill. Changes in acceleration and starting speed are only applied at standstill. The maximum speed can be changed at will. Any change in maximum speed is reached with a ramp.
The motor is freewheeling. This means that the windings are not magnetized and the motor has no holding torque.
It is not recommended to change from step mode to fix speed mode. It is better to stop the engine first and then change the mode. However, when changing from one of these two modes to free running mode, the motor will simply come to a stop without any braking effect (all windings will be non-magnetized). When resetting the module, the motor keeps the current step (the windings are still magnetized).
Setting the bit 0 in the configuration register of the subdevice will reset the steps of all motors.
Offset | Size [byte] | Name | r/w | Const | Description |
---|---|---|---|---|---|
0x20 | 4 | base_clk | r | yes | base clock in Hz |
0x24 | 4 | conf_0 | r/w | no | motor 0: motor configuration register |
0x28 | 4 | conf_1 | r/w | no | motor 1: motor configuration register |
.. | 4 | .. | r/w | no | .. |
0xhh | 4 | set_conf_0 | w | no | motor 0: set bits in conf_0 (atomic) |
0xhh+4 | 4 | set_conf_1 | w | no | motor 1: set bits in conf_0 (atomic) |
.. | 4 | .. | w | no | .. |
0xii | 4 | reset_conf_0 | w | no | motor 0: reset bits in conf_0 (atomic) |
0xii+4 | 4 | reset_conf_1 | w | no | motor 1: reset bits in conf_0 (atomic) |
.. | 4 | .. | w | no | .. |
0xkk | 4 | start_0 | r/w | no | motor 0: prescaler for start speed |
0xkk+4 | 4 | start_1 | r/w | no | motor 1: prescaler for start speed |
.. | 4 | .. | r/w | no | .. |
0xll | 4 | top_0 | r/w | no | motor 0: prescaler for top speed |
0xll+4 | 4 | top_1 | r/w | no | motor 1: prescaler for top speed |
.. | 4 | .. | r/w | no | .. |
0xnn | 4 | acc_0 | r/w | no | motor 0: acceleration prescaler between start and top speed |
0xnn+4 | 4 | acc_1 | r/w | no | motor 1: acceleration prescaler between start and top speed |
.. | 4 | .. | r/w | no | .. |
0xoo | 4 | dest_steps_0 | r/w | no | motor 0: destination position (number of steps) |
0xoo+4 | 4 | dest_steps_1 | r/w | no | motor 1: destination position (number of steps) |
.. | 4 | .. | r/w | no | .. |
0xpp | 4 | curr_steps_0 | r | no | motor 0: current position (number of steps) |
0xpp+4 | 4 | curr_steps_1 | r | no | motor 1: current position (number of steps) |
.. | 4 | .. | r | no | .. |
31 | … | 06 | 05 | 04..03 | 02 | 01 | 00 |
Reset Step Counter | Start | Run Mode | Two Phase | Full Step | Direction |
The motor configuration register can be reading or writing at address conf_x. You can set a given set of bits to '1' by writing to set_conf_x and you can reset to '0' with reset_conf_x.
When a motor is started it will start with its start speed and accelerate to its top speed. Start speed, top speed and acceleration can be configured by setting their corresponding prescaler values. Start and top speed are calculated by the base clock of the submodule divided by the prescaler value. The acceleration is calculated by the base clock of the submodule divided by 2 times the prescaler value. The acceleration is divided by two within the module because the motor accelerates with each trigger edge. Therefore the LSB is not considered by the acceleration.
An interrupt is asserted when the motor reaches its final position.
This subdevice uses 4 pins per channel on the FPGA. They are called A,A',B,B'. For the connection, a distinction must be made between unipolar and bipolar motors.
Unipolar: In unipolar motors, each coil can be connected to one output. In order to maintain the direction of rotation, the outputs must be connected to the motor in the above mentioned order in CW orientation.
Bipolar: In the case of the bipolar motor, the outputs are to be considered as pairs. A, A' and B, B' belong together and thus on a common coil. When A is high, the coil is positively magnetized and when A' is high, the coil is negatively magnetized.
Used to connect a large number of IRQ lines coming from flink devices to a limited number of IRQ lines going to the interrupt control hardware of the processor.
Offset | Size [byte] | Name | r/w | Const | Description |
---|---|---|---|---|---|
0x20 | 4 | irq_line_0 | r/w | no | IRQ line 0: number of flink IRQ |
0x24 | 4 | irq_line_1 | r/w | no | IRQ line 1: number of flink IRQ |
.. | 4 | .. | r/w | no | .. |
The status register in the subheader is unused with this function. In the configuration register setting the bit 0 will reset the subdevice.
Each signal of the output vector has a register describing which signal of the input vector to connect to.
0 ⇒ default value
1 ⇒ first signal (LSB) of the input vector.
2 ⇒ second signal of the input vector.
…