Position Feedback Module

This module provides a Service which starts one or two Position Sensor Services among BiSS, REM 16MT, REM 14, Hall and QEI. The service can also manage the GPIO ports.

The service takes as parameters:
  • ports for the different sensors
  • one config structure for each of the sensor services started (so 2 structures).
  • client interfaces to the shared memory for each of the sensor services (2).
  • server interfaces for the sensor services (2).

The service will initialize the ports and detect wrong configurations (for exemple starting two sensor services using the same ports). Then it will start one or two services. The second service is optional and will not be started if no config structure or server interface is provided it. The types of the sensor services started are set using the sensor_type parameter of the config structure.

The service provides an interface which can be used to get or set the configuration or the position data. This interface should only be used for configuration and debug purposes. For periodic data reading the shared memory should be used.

The shared memory is useful for other services to retrieve position and velocity data without blocking. There are 5 modes to configure which data is sent to the shared memory:
  • send nothing
  • send the electrical angle for commutation and the absolute position/velocity for motion control
  • send the electrical angle for commutation and the absolute position/velocity for secondary feedback (for display only)
  • send only the absolute position/velocity for motion control
  • send only the absolute position/velocity for secondary feedback (for display only)

The mode is set using the sensor_function parameter of the config structure.

It is possible to switch the sensor service type at runtime. You need fist to update the config structure to set the sensor_type that you want. Then you call the exit() interface which will restart the Position Feedback Service with the new sensor service.

This Service should always run over an IF2 Tile so it can access the ports to your SOMANET Drive module.

../../../../../../_images/core-diagram-position-feedback-interface.png

How to use

Important

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, which illustrates the use of this module.

  1. First, add all the SOMANET Motor Control modules to your app Makefile. The Position Feedback Service needs all the sensor modules it supports (BiSS, REM 16MT, REM 14, Hall and QEI).

    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_incremental_encoder module_encoder_rem_14 module_encoder_rem_16mt module_serial_encoder module_spi_master
    

    Note

    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 Position Feedback Service header position_feedback_service.h in your app.

  3. Instantiate the ports needed for the sensors.

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

  5. Optionally, instantiate the shared memory interface.

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

    The service configuration contains generic sensor parameters and also structures for sensor specific parameters. You need to fill up all the parameters for the sensor you want to use. You also need to fill up all the generic parameters especially tile_usec, resolution, velocity_compute_period and sensor_function. As the service supports two sensors there is two configurations structures. The sensor type is selected with the sensor_type parameter.

  7. At whichever other core, now you can perform calls to the Position Feedback Service through the interfaces connected to it. Or if it is enabled you can read the position using the shared memory.

    #include <CoreC2X.bsp>                          //Board Support file for SOMANET Core C2X device
    #include <Drive1000-rev-c4.bsp>     //Board Support file for SOMANET Drive module
                                        //(select your board support files according to your device)
    
    // 2. Include the Position Feedback Service header
    #include <position_feedback_service.h>
    
    // 3. Instantiate the ports needed for the sensors.
    HallEncSelectPort hall_enc_select_port = SOMANET_DRIVE_ENCODER_PORTS_INPUT_MODE_SELECTION;
            port ? qei_hall_port_1 = SOMANET_DRIVE_ENCODER_1_PORT;
            port ? qei_hall_port_2 = SOMANET_DRIVE_ENCODER_2_PORT;
            port ?gpio_port_0 = SOMANET_DRIVE_GPIO_D0;
            port ?gpio_port_1 = SOMANET_DRIVE_GPIO_D1;
            port ?gpio_port_2 = SOMANET_DRIVE_GPIO_D2;
            port ?gpio_port_3 = SOMANET_DRIVE_GPIO_D3;
    
    int main(void)
    {
        // 4. Instantiate the interfaces array for the Service-Clients communication.
        interface PositionFeedbackInterface i_position_feedback_1[3];
        interface PositionFeedbackInterface i_position_feedback_2[3];
    
        // 5. Instantiate the shared memory interface.
        interface shared_memory_interface i_shared_memory[3];
    
        par
        {
    
            on tile[IF2_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 */
                {
                    PositionFeedbackConfig position_feedback_config;
                position_feedback_config.sensor_type = SENSOR_1_TYPE;
                position_feedback_config.resolution  = SENSOR_1_RESOLUTION;
                position_feedback_config.polarity    = SENSOR_1_POLARITY;
                position_feedback_config.velocity_compute_period = SENSOR_1_VELOCITY_COMPUTE_PERIOD;
                position_feedback_config.pole_pairs  = MOTOR_POLE_PAIRS;
                position_feedback_config.tile_usec   = IF2_TILE_USEC;
                position_feedback_config.max_ticks   = SENSOR_MAX_TICKS;
                position_feedback_config.offset      = HOME_OFFSET;
                position_feedback_config.sensor_function = SENSOR_1_FUNCTION;
    
                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.biss_config.data_port_signal_type = BISS_DATA_PORT_SIGNAL_TYPE;
    
                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_settings          = REM_14_SENSOR_NOISE_SETTINGS;
                position_feedback_config.rem_14_config.dyn_angle_error_comp    = REM_14_DYN_ANGLE_ERROR_COMPENSATION;
                position_feedback_config.rem_14_config.abi_resolution_settings = REM_14_ABI_RESOLUTION_SETTINGS;
    
                position_feedback_config.qei_config.number_of_channels = QEI_SENSOR_NUMBER_OF_CHANNELS;
                position_feedback_config.qei_config.signal_type        = QEI_SENSOR_SIGNAL_TYPE;
                position_feedback_config.qei_config.port_number        = QEI_SENSOR_PORT_NUMBER;
                position_feedback_config.qei_config.ticks_lost_threshold = QEI_SENSOR_TICKS_LOST;
    
                position_feedback_config.hall_config.port_number = HALL_SENSOR_PORT_NUMBER;
                position_feedback_config.hall_config.hall_state_angle[0]=HALL_STATE_1_ANGLE;
                position_feedback_config.hall_config.hall_state_angle[1]=HALL_STATE_2_ANGLE;
                position_feedback_config.hall_config.hall_state_angle[2]=HALL_STATE_3_ANGLE;
                position_feedback_config.hall_config.hall_state_angle[3]=HALL_STATE_4_ANGLE;
                position_feedback_config.hall_config.hall_state_angle[4]=HALL_STATE_5_ANGLE;
                position_feedback_config.hall_config.hall_state_angle[5]=HALL_STATE_6_ANGLE;
    
                position_feedback_config.gpio_config[0] = GPIO_CONFIG_1;
                position_feedback_config.gpio_config[1] = GPIO_CONFIG_2;
                position_feedback_config.gpio_config[2] = GPIO_CONFIG_3;
                position_feedback_config.gpio_config[3] = GPIO_CONFIG_4;
    
                //setting second sensor
                PositionFeedbackConfig position_feedback_config_2 = position_feedback_config;
                position_feedback_config_2.sensor_type = 0;
                if (SENSOR_2_FUNCTION != SENSOR_FUNCTION_DISABLED) //enable second sensor
                {
                    position_feedback_config_2.sensor_type = SENSOR_2_TYPE;
                    position_feedback_config_2.polarity    = SENSOR_2_POLARITY;
                    position_feedback_config_2.resolution  = SENSOR_2_RESOLUTION;
                    position_feedback_config_2.velocity_compute_period = SENSOR_2_VELOCITY_COMPUTE_PERIOD;
                    position_feedback_config_2.sensor_function = SENSOR_2_FUNCTION;
                }
    
                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_1,
                        position_feedback_config_2, i_shared_memory[1], i_position_feedback_2);
                }
            }
    
            on tile[APP_TILE]:
            {
                int count_1, position_1, status_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, status_1 } = 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();
    
                /* get position from Sensor 2 */
                { count_2, position_2, status_2 } = i_position_feedback_2[0].get_position();
                angle_2 = i_position_feedback_2[0].get_angle();
                velocity_2 = i_position_feedback_2[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;
    }
    

API

Types

GPIOType

GPIO port type.

Enum Values:

GPIO_OFF

GPIO port off.

GPIO_INPUT

Input GPIO port.

GPIO_INPUT_PULLDOWN

Input GPIO port with pulldown.

GPIO_OUTPUT

Output GPIO port.

SensorFunction

Sensor function type to select which data to write to the shared memory.

Enum Values:

SENSOR_FUNCTION_DISABLED

Send nothing.

SENSOR_FUNCTION_COMMUTATION_AND_MOTION_CONTROL

Send the electrical angle for commutation and the absolute position/velocity for motion control.

SENSOR_FUNCTION_COMMUTATION_AND_FEEDBACK_DISPLAY_ONLY

Send the electrical angle for commutation and the absolute position/velocity for secondary feedback (for display only)

SENSOR_FUNCTION_MOTION_CONTROL

Send only the absolute position/velocity for motion control.

SENSOR_FUNCTION_FEEDBACK_DISPLAY_ONLY

Send only the absolute position/velocity for secondary feedback (for display only)

SENSOR_FUNCTION_COMMUTATION_ONLY

Send only the absolute position/velocity for secondary feedback (for display only)

SensorError

Type for Sensor Error.

Enum Values:

SENSOR_NO_ERROR
SENSOR_REM_16MT_WEAK_MAG_FIELD_ERROR
SENSOR_REM_16MT_MT_COUNTER_ERROR
SENSOR_REM_16MT_ST_CORDIC_ERROR
SENSOR_REM_16MT_MT_SPEED_OVERLOW_ERROR
SENSOR_REM_16MT_FILTER_CONFIG_ERROR
SENSOR_REM_16MT_FILTER_SPEED_OVERLOW_ERROR
SENSOR_REM_16MT_UNKNOWN_CMD_ERROR
SENSOR_REM_16MT_CONFIG_ERROR
SENSOR_BISS_ERROR_BIT_ERROR
SENSOR_BISS_WARNING_BIT_ERROR
SENSOR_BISS_ERROR_AND_WARNING_BIT_ERROR
SENSOR_BISS_NO_ACK_BIT_ERROR
SENSOR_BISS_NO_START_BIT_ERROR
SENSOR_CHECKSUM_ERROR
SENSOR_BISS_DATA_LINE_ERROR
SENSOR_QEI_INDEX_LOSING_TICKS
SENSOR_HALL_FAULT
SENSOR_INCREMENTAL_FAULT
SENSOR_POSITION_FAULT
SENSOR_NO_ERROR
SENSOR_REM_16MT_WEAK_MAG_FIELD_ERROR
SENSOR_REM_16MT_MT_COUNTER_ERROR
SENSOR_REM_16MT_ST_CORDIC_ERROR
SENSOR_REM_16MT_MT_SPEED_OVERLOW_ERROR
SENSOR_REM_16MT_FILTER_CONFIG_ERROR
SENSOR_REM_16MT_FILTER_SPEED_OVERLOW_ERROR
SENSOR_REM_16MT_UNKNOWN_CMD_ERROR
SENSOR_REM_16MT_CONFIG_ERROR
SENSOR_BISS_ERROR_BIT_ERROR
SENSOR_BISS_WARNING_BIT_ERROR
SENSOR_BISS_ERROR_AND_WARNING_BIT_ERROR
SENSOR_BISS_NO_ACK_BIT_ERROR
SENSOR_BISS_NO_START_BIT_ERROR
SENSOR_CHECKSUM_ERROR
SENSOR_BISS_DATA_LINE_ERROR
SENSOR_QEI_INDEX_LOSING_TICKS
SENSOR_HALL_FAULT
SENSOR_INCREMENTAL_FAULT
SENSOR_POSITION_FAULT
EncoderPortNumber

Type for Encoder Port.

There are two identical encoder ports which can be used for Hall, QEI and BiSS.

Enum Values:

ENCODER_PORT_1

Encoder connector 1.

ENCODER_PORT_2

Encoder connector 2.

ENCODER_PORT_EXT_D0

Encoder connector 3.

ENCODER_PORT_EXT_D1

Not used anymore.

ENCODER_PORT_EXT_D2

Not used anymore.

ENCODER_PORT_EXT_D3

Not used anymore.

PositionFeedbackPortsLocation

Type for port pointer location.

Enum Values:

POSITION_FEEDBACK_PORTS_NULL

port is not available

POSITION_FEEDBACK_PORTS_1

port is for service 1

POSITION_FEEDBACK_PORTS_2

port is for service 2

POSITION_FEEDBACK_PORTS_BISS_CLOCK_1

port is on biss clock 1

POSITION_FEEDBACK_PORTS_BISS_CLOCK_2

port is on biss clock 2

POSITION_FEEDBACK_PORTS_BISS_DATA_1

port is on biss data 1

POSITION_FEEDBACK_PORTS_BISS_DATA_2

port is on biss data 2

PositionFeedbackPortsCheck

Structure to keep track of port pointers locations.

Structure Members:

PositionFeedbackPortsLocation hall_enc_select_port

hall_enc_select_port

PositionFeedbackPortsLocation gpio_ports

gpio_ports

PositionFeedbackPortsLocation qei_hall_port_1

qei_hall_port_1

PositionFeedbackPortsLocation qei_hall_port_2

qei_hall_port_2

PositionFeedbackPortsLocation spi_ports

spi_ports

PositionFeedbackConfig

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 tile_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.

SPIPorts

Structure for SPI ports and clock blocks.

Structure Members:

spi_master_class spi_class
port *movable slave_select
HallEncSelectPort

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:

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

int hall_enc_select_inverted

Select if the logic is inverted (0 normal, 1 inverted)

Service

void position_feedback_service(port ?qei_hall_port_1, port ?qei_hall_port_2, HallEncSelectPort & ?hall_enc_select_port_struct, SPIPorts & ?spi_ports, port ?gpio_port_0, port ?gpio_port_1, port ?gpio_port_2, port ?gpio_port_3, PositionFeedbackConfig &position_feedback_config_1, client interface shared_memory_interface ?i_shared_memory_1, server interface PositionFeedbackInterface i_position_feedback_1[3], PositionFeedbackConfig & ?position_feedback_config_2, client interface shared_memory_interface ?i_shared_memory_2, server interface PositionFeedbackInterface(& ?i_position_feedback_2)[3])

Service to read and position, velocity and electrical angle from various position sensors (Hall, QEI, BiSS, REM 16MT, REM 14) It can also manages the GPIO ports.

The service can simultaneously run 2 sensor services and manage the GPIO ports. Is uses the shared memory to send position, velocity and electrical angle to the other services.

Parameters:
  • qei_hall_port_1 – Hall/QEI input port number 1
  • qei_hall_port_2 – Hall/QEI input port number 2
  • hall_enc_select_port – port used to select the mode (differential or not) of Hall/qei ports
  • spi_ports – SPI ports and clock blocks
  • gpio_port_0 – GPIO port number 0
  • gpio_port_1 – GPIO port number 1
  • gpio_port_2 – GPIO port number 2
  • gpio_port_3 – GPIO port number 3
  • position_feedback_config_1 – Config structure for first service
  • i_shared_memory_1 – Shared memory class for first service
  • i_position_feedback_1 – Server class for first service
  • position_feedback_config_2 – Config structure for second service
  • i_shared_memory_2 – Shared memory class for second service
  • i_position_feedback_2 – Server class for second service

Interface

interface PositionFeedbackInterface

Interface to communicate with the Position Feedback Service.

[[notification]] slave void notification()

Notifies the interested parties that a new notification is available.

[[clears_notification]] int get_notification()

Provides the type of notification currently available.

Returns:type of the notification
unsigned int get_angle(void)

Get the electrical angle.

Returns:electrical angle
{ int, unsigned int, SensorError } g get_position(void)

Get the absolute multiturn position, the singleturn position and the sensor status.

Returns:Absolute multiturn position in ticks
Returns:Singleturn position in ticks
Returns:Sensor status
int get_velocity(void)

Get the velocity in Round per minute (rpm)

Returns:velocity in rpm
PositionFeedbackConfig get_config(void)

Get the position feedback configuration.

Returns:position feedback configuration
void set_config(PositionFeedbackConfig in_config)

the position feedback configuration

Parameters:
  • in_config – the position feedback configuration to set
void set_position(int in_count)

Reset the absolute position to a new value.

Parameters:
  • the – new value to set
unsigned int send_command(int opcode, int data, int data_bits)

Send a command to the sensor (currently only supported for REM 16MT)

Parameters:
  • opcode – of the command
  • data – of the command
  • data_bits – the number of bits of data
Returns:

return status of the command

int gpio_read(int gpio_num)

Read a GPIO port.

Parameters:
  • gpio_num – The number of GPIO port to read
Returns:

Value read

void gpio_write(int gpio_num, int in_value)

Write to a GPIO port.

Parameters:
  • gpio_num – The number of the GPIO port
  • in_value – Value to write
void exit()

Exit the current sensor service and restart the position.

Functions

int tickstobits(uint32_t ticks)

Convert the number of tick per turn into the number of resolution bits.

Parameters:
  • ticks – the number of ticks per turn
Returns:

the number of resolution bits

void multiturn(int &count, int last_position, int position, int ticks_per_turn)

Compute the multiturn position using the last measured position and the current position.

Parameters:
  • count – The multiturn position
  • last_position – The last measured position
  • position – The current position
  • ticks_per_turn – The number of ticks per turn
void write_shared_memory(client interface shared_memory_interface ?i_shared_memory, SensorFunction sensor_function, int count, int position, int velocity, int angle, int hall_state, unsigned int qei_index_found, SensorError sensor_error, SensorError last_sensor_error, unsigned int timestamp)

Write position, velocity and electrical angle to the shared memory.

Parameters:
  • i_shared_memory – The client class to the shared memory
  • sensor_function – The sensor function to select which data to write.
  • count – The absolute multiturn position
  • velocity – The velocity
  • angle – The electrical angle
  • hall_state – The Hall pin state if Hall sensor is used
  • sensor_error – the sensor error status
  • timestamp – timestamp in microseconds of when the position data was read
int velocity_compute(int difference, int timediff, int resolution)

Compute the velocity in rpm.

Parameters:
  • difference – The difference in ticks between the 2 last measurements
  • timediff – The time difference between the 2 last measurements
  • resolution – The number of ticks per turn (to convert ticks to rpm)
Returns:

velocity in rpm

int gpio_read(int gpio_num)

Read a GPIO port.

Parameters:
  • gpio_num – The number of GPIO port to read
Returns:

Value read

void gpio_write(int gpio_num, int in_value)

Write to a GPIO port.

Parameters:
  • gpio_num – The number of the GPIO port
  • in_value – Value to write
void gpio_shared_memory(port *(& ?gpio_ports)[4], PositionFeedbackConfig &position_feedback_config, client interface shared_memory_interface ?i_shared_memory, int service_number)

Read/Write GPIO data from/to the shared memory.

The input data is read from the GPIO ports and written to the shared memory. The output data is read from the shared memory and written to the GPIO ports.

Parameters:
  • gpio_ports – The GPIO ports array
  • position_feedback_config – The position feedback service configuration
  • i_shared_memory – The client class to the shared memory
  • service_number – Service number (1 or 2) use to enable GPIO only on 1.