AN 957: Time-Sensitive Networking for Drive-on-Chip Design Example

ID 683707
Date 10/30/2021
Public
Document Table of Contents

4.2. Creating a Basic C Program for Motor Control

Creating a program to talk to the drive-on-chip subsystem from the Linux system uses the shared memory mechanism implemented during the Qsys system build.

  1. In the C program, set up the memory locations by using defines:
    #define DEBUG_RAM_BASE 0xc4001000 #define DEBUG_ADDR_SPACE_PER_AXIS 64 /* Offsets into debug mem */ #define DOC_DBG_SPEED 10 #define DOC_DBG_POSITION 12 #define DOC_DBG_I_PI_KP 18 #define DOC_DBG_I_PI_KI 19 #define DOC_DBG_SPEED_PI_KP 20 #define DOC_DBG_SPEED_PI_KI 21 #define DOC_DBG_SPEED_SETP0 22 #define DOC_DBG_POS_SETP0 25 #define DOC_DBG_WAVE_DEMO_MODE 29 #define DOC_DBG_POS_SPEED_LIMIT 30 #define DOC_DBG_POS_PI_KP 31 #define DOC_DBG_TRACE_DEPTH 58

    These parameters are identical to the ones described in the motor control application program (Nios II program)..

  2. Create functions to read and write to the motor control application:
    //Read debug mem unsigned int get_motor_param(unsigned int axis, unsigned int param) { return debug_base[axis * DEBUG_ADDR_SPACE_PER_AXIS + param]; } //Write debug mem void set_motor_param(unsigned int axis, unsigned int param, unsigned int val) { debug_base[axis * DEBUG_ADDR_SPACE_PER_AXIS + param] = val; }
  3. In the main map the memory by using the following lines:
    int _fdmem; const char memDevice[] = "/dev/mem"; _fdmem = open(memDevice, O_RDWR | O_SYNC); if (_fdmem < 0) { printf("Failed to open the /dev/mem !\n"); return 0; } else { printf("open /dev/mem successful!\n"); } /* mmap() debug memory */ int debug_size = 512; printf("Mapping %i bytes for debug_data\n", debug_size); debug_base = (unsigned int *)(mmap(0, debug_size, PROT_READ | PROT_WRITE, MAP_SHARED, _fdmem, DEBUG_RAM_BASE)); if ((void *)debug_base == MAP_FAILED) { printf("Failed to map debug memory\n"); return -1; } else { printf("Debug mem base : %x\n", (unsigned int)debug_base); }
  4. Test the motor movement by reading and writing to the drive-on-chip subsystem, for example to set the motor to the position 100 degrees:
    set_motor_param(0, DOC_DBG_WAVE_DEMO_MODE, 1); //Set the axis 0 to position mode set_motor_param(1, DOC_DBG_WAVE_DEMO_MODE, 1); //Set the axis 1 to position mode set_motor_param(0, DOC_DBG_SPEED_SETP0, 100); //Set axis 0 pos to 100 degrees set_motor_param(1, DOC_DBG_SPEED_SETP0, 100); //Set axis 1 pos to 100 degrees
  5. In the same way use the function get_motor_param to retrieve information from the drive-on-chip subsystem such as position of the shaft, speed, motor control parameters like Kp, Ki or set the maximum speed limit..
  6. Compile the C program using the following command:
    >> arm-linux-gnueabihf-gcc <program_name>.c -O3 -march=armv7-a
  7. Copy the program to the development board via scp and test the motor control.