Serial Encoder Module

This module provides a Service that will read and process the data coming from an Encoder communicating over a serial protocol like BiSS or SPI.

This service can run independently but is meant to be used by the Position Feedback Module that is why it uses the same communication interface.

The Service should always run over an IFM tile so it can access the ports to your SOMANET IFM device.


How to use


We assume that you are using SOMANET Base and your app includes the required board support files for your SOMANET device.

See also

You might find useful the Position feedback Demo example app, which illustrates the use of this module.

  1. First, add all the SOMANET Motion Control modules to your app Makefile.

    USED_MODULES = configuration_parameters module_biss_encoder lib_bldc_torque_control module_board-support module_hall_sensor module_shared_memory module_utils module_position_feedback module_serial_encoder module_encoder_rem_14 module_encoder_rem_16mt module_incremental_encoder module_spi_master


    Not all modules will be required, but when using a library it is recommended to include always all the contained modules. This will help solving internal dependency issues.

  2. Include the Encoder Service header serial_encoder_service.h.h in your app.

  3. Instantiate the ports where the Service will be reading the Encoder Sensor feedback signals.

    Depending on the configuration the Serial Encoder service uses qei_hall_port 1 or 2, p_hall_enc_select, a GPIO port and a clock block (in SPI ports) for BiSS. SPI ports and GPIO ports for SPI. The ports structures are defined in position_feedback_service.h.

  4. Inside your main function, instantiate the interfaces array for the Service-Clients communication.

  5. Optionally, instantiate the shared memory interface.

  6. At your IFM tile, instantiate the Service. For that, first you will have to fill up your Service configuration.

    The service uses the same configuration structure as the Position Feedback Module. You need to fill up all the generic sensor parameters especially ifm_usec, resolution, velocity_compute_period and sensor_function. And you need to fill up sensor specific parameters depending on the sensor you want to use (BiSS, REM 14, REM 16MT).

  7. At whichever other core, now you can perform calls to the Encoder Service through the interfaces connected to it.

    #include <CORE_C22-rev-a.bsp>   //Board Support file for SOMANET Core C22 device
    #include <IFM_DC100-rev-b.bsp>  //Board Support file for SOMANET IFM DC100 device
                                    //(select your board support files according to your device)
    // 2. Include the Hall Service header
    #include <serial_encoder_service.h>
    // 3. Instantiate the ports needed for the sensor.
    QEIHallPort qei_hall_port_1 = SOMANET_IFM_HALL_PORTS;
    QEIHallPort qei_hall_port_2 = SOMANET_IFM_QEI_PORTS;
    HallEncSelectPort hall_enc_select_port = SOMANET_IFM_QEI_PORT_INPUT_MODE_SELECTION;
    SPIPorts spi_ports = SOMANET_IFM_SPI_PORTS;
    port ?gpio_port_0 = SOMANET_IFM_GPIO_D0;
    port ?gpio_port_1 = SOMANET_IFM_GPIO_D1;
    port ?gpio_port_2 = SOMANET_IFM_GPIO_D2;
    port ?gpio_port_3 = SOMANET_IFM_GPIO_D3;
    int main(void)
        // 4. Instantiate the interfaces array for the Service-Clients communication.
        interface PositionFeedbackInterface i_position_feedback_1[3];
        // 5. Instantiate the shared memory interface.
        interface shared_memory_interface i_shared_memory[3];
            on tile[IFM_TILE]: par {
                // 5. Start the shared memory service
                shared_memory_service(i_shared_memory, 3);
                // 6. Fill up your Service configuration and instantiate the Service.
                /* Position feedback service */
                    //set default parameters
                    PositionFeedbackConfig position_feedback_config;
                    position_feedback_config.sensor_type = BISS_SENSOR;
                    position_feedback_config.resolution  = BISS_SENSOR_RESOLUTION;
                    position_feedback_config.polarity    = NORMAL_POLARITY;
                    position_feedback_config.velocity_compute_period = BISS_SENSOR_VELOCITY_COMPUTE_PERIOD;
                    position_feedback_config.pole_pairs  = POLE_PAIRS;
                    position_feedback_config.ifm_usec    = IFM_TILE_USEC;
                    position_feedback_config.max_ticks   = SENSOR_MAX_TICKS;
                    position_feedback_config.offset      = 0;
                    position_feedback_config.sensor_function = SENSOR_FUNCTION_COMMUTATION_AND_MOTION_CONTROL;
                    position_feedback_config.biss_config.multiturn_resolution = BISS_MULTITURN_RESOLUTION;
                    position_feedback_config.biss_config.filling_bits = BISS_FILLING_BITS;
                    position_feedback_config.biss_config.crc_poly = BISS_CRC_POLY;
                    position_feedback_config.biss_config.clock_frequency = BISS_CLOCK_FREQUENCY;
                    position_feedback_config.biss_config.timeout = BISS_TIMEOUT;
                    position_feedback_config.biss_config.busy = BISS_BUSY;
                    position_feedback_config.biss_config.clock_port_config = BISS_CLOCK_PORT;
                    position_feedback_config.biss_config.data_port_number = BISS_DATA_PORT_NUMBER;
                    position_feedback_config.rem_16mt_config.filter = REM_16MT_FILTER;
                    position_feedback_config.rem_14_config.hysteresis     = REM_14_SENSOR_HYSTERESIS ;
                    position_feedback_config.rem_14_config.noise_setting  = REM_14_SENSOR_NOISE;
                    position_feedback_config.rem_14_config.dyn_angle_comp = REM_14_SENSOR_DAE;
                    position_feedback_config.rem_14_config.abi_resolution = REM_14_SENSOR_ABI_RES;
                    position_feedback_service(qei_hall_port_1, qei_hall_port_2, hall_enc_select_port, spi_ports, gpio_port_0, gpio_port_1, gpio_port_2, gpio_port_3,
                                              position_feedback_config, i_shared_memory[0], i_position_feedback,
                                              null, null, null);
            on tile[APP_TILE]:
                int count_1, position_1, angle_1, velocity_1;
                int count_2, position_2, status_2, angle_2, velocity_2;
                // 7. Call to the Position Feddback Service through the interfaces connected to it.
                /* get position from Sensor 1 */
                { count_1, position_1, void } = i_position_feedback_1[0].get_position();
                angle_1 = i_position_feedback_1[0].get_angle();
                velocity_1 = i_position_feedback_1[0].get_velocity();
                // 7. You can also read the position using the shared memory.
                UpstreamControlData upstream_control_data = i_shared_memory[2].read();
                angle_1 = upstream_control_data.angle;
                count_1 = upstream_control_data.position;
                velocity_1 = upstream_control_data.velocity;
        return 0;




Configuration structure of the position feedback service.

Structure Members:

SensorType sensor_type

Select the sensor type.

SensorFunction sensor_function

Select which data to write to shared memory.

SensorPolarity polarity

Encoder polarity.

UsecType ifm_usec

Number of clock ticks in a microsecond >

int pole_pairs

Number of pole pairs.

int resolution

Number of ticks per turn.

int offset

Offset (in ticks) added to the absolute multiturn position (count).

Does not affect the electrical angle

int max_ticks

The multiturn position is reset to 0 when reached.

int velocity_compute_period

Velocity compute period in microsecond.

Is also the polling period to write to the shared memory

BISSConfig biss_config

BiSS sensor configuration.

REM_16MTConfig rem_16mt_config

REM 16MT sensor configuration.

REM_14Config rem_14_config

REM 14 configuration.

QEIConfig qei_config

QEI sensor configuration.

HallConfig hall_config

Hall sensor configuration.

GPIOType gpio_config

GPIO configuration.


Structure type to define the BiSS sensor configuration.

Structure Members:

int multiturn_resolution

Number of bits of multiturn resolution.

int singleturn_resolution

Number of bits of singleturn resolution.

int filling_bits

Number of filling bits between the singleturn data status data.

int crc_poly

CRC polynom in reverse representation: x^0 + x^1 + x^6 is 0b110000.

int clock_frequency

BiSS output clock frequency in kHz, supported frequencies depend on IFM Tile frequency.

int timeout

Timeout after a BiSS read in microseconds.

int busy

maximum number of bits to read before the start bit (= maximum duration of ACK bit)

BISSClockPortConfig clock_port_config

Configure of the biss clock port (GPIO or hall_enc_select_port)

EncoderPortNumber data_port_number

Configure which port is used for the biss input data.


Structure type to define the REM 14 sensor configuration.

Structure Members:

REM_14_Noise noise_settings

Noise setting.

In 3.3V operation, VDD and VREG must be tied together. In this configuration, normal noise performance (ONL) is available at reduced maximum temperature (125°C) by clearing NOISESET to 0. When NOISESET is set to 1, the full temperature range is available with reduced noise performance (ONH).

REM_14_DynAngleComp dyn_angle_error_comp

Disable Dynamic Angle Error Compensation.

REM_14_Hysteresis hysteresis

Hysteresis for 11 Bit ABI Resolution.

REM_14_ABIResolution abi_resolution_settings

Resolution of ABI (0 = 11 bits, 1 = 10 bits)


Structure type to define the REM16 Sensor configuration.

Structure Members:

int filter

filter parameter for REM 16MT sensor.

0x00 to disable. 0x02 to 0x09 to enable. 0x09 is the strongest.


Structure for Hall/QEI input ports (can also be used for BiSS)

Structure Members:

in port p_qei_hall

4-bit Port for Encoder, BiSS or Hall signals input.


Structure for the hall_enc_select port used to select the mode (differential or not) of Hall/qei ports.

Also used for the BiSS clock output

Structure Members:

out port p_hall_enc_select

[Nullable] Port to control the signal input circuitry (if applicable in your SOMANET device).

Also used for the BiSS clock output


Structure for SPI ports and clock blocks.

Structure Members:

spi_master_class spi_class
port *movable slave_select


void serial_encoder_service(QEIHallPort *qei_hall_port_1, QEIHallPort *qei_hall_port_2, HallEncSelectPort *hall_enc_select_port, SPIPorts *spi_ports, port *(& ?gpio_ports)[4], int hall_enc_select_config, PositionFeedbackConfig &position_feedback_config, client interface shared_memory_interface ?i_shared_memory, interface PositionFeedbackInterface server i_position_feedback[3], int gpio_on)

Service to read and process data from an Position Sensor with a serial class (SPI or BiSS).

  • qei_hall_port_1 – BiSS input port number 1
  • qei_hall_port_2 – BiSS input port number 2
  • hall_enc_select_port – port used to select the mode (differential or not) of Hall/QEI/BiSS ports
  • spi_ports – SPI ports and clock blocks
  • gpio_ports – GPIO ports array
  • hall_enc_select_config – config to select the mode (differential or not) of Hall/QEI/BiSS ports
  • position_feedback_config – Configuration for the service.
  • i_shared_memory – Client class to write the position data to the shared memory.
  • i_position_feedback – Server class used by clients for configuration and direct position read.
  • gpio_on – Set to 1 to enable GPIO read/write.