Driving Stepper Motors for Focus Adjustment on Allwinner H713/H618 Platforms
Hardware Configuration
Motor Driver Connection
Connect the development board to the stepper motor driver using the following GPIO pin assignments:
- GPIO PC5 -> Driver IN1
- GPIO PC6 -> Driver IN2
- GPIO PC8 -> Driver IN3
- GPIO PC9 -> Driver IN4
Ensure proper 5V and GND connections are established between the boards.
Stepper Motor Excitation Methods
Single-Phase Excitation (4-Phase, 4-Step)
Activates one coil at a time in sequence.
- Advantages: Simple implementation, low power consumption
- Disadvantages: Lower torque, increased vibration
Sequence: A → B → C → D GPIO pattern: IN1 high → IN2 high → IN3 high → IN4 high
Dual-Phase Excitation (4-Phase, 4-Step)
Activates two coils simultaneous during each step.
- Advantages: Higher torque, reduced vibration
- Disadvantages: Standard step angle resolution
Sequence: AB → BC → CD → DA GPIO pattern: IN1+IN2 high → IN2+IN3 high → IN3+IN4 high → IN4+IN1 high
Hybrid Excitation (4-Phase, 8-Step)
Alternates between single and dual-phase activation for half-step operation.
- Advantages: Higher precision, smoother operation
Sequence: A → AB → B → BC → C → CD → D → DA
Binary Phase Representation
Counter-Clockwise Rotation
uint8_t phase_CCW[8] = {0x08, 0x0C, 0x04, 0x06, 0x02, 0x03, 0x01, 0x09};
Binary: 1000, 1100, 0100, 0110, 0010, 0011, 0001, 1001
Clockwise Rotation
uint8_t phase_CW[8] = {0x09, 0x01, 0x03, 0x02, 0x06, 0x04, 0x0C, 0x08};
Binary: 1001, 0001, 0011, 0010, 0110, 0100, 1100, 1000
Device Tree Configuration
Add the following configuration to board.dts, ensuring GPIO conflicts are resolved:
focus_motor: focus_motor {
compatible = "motor-control";
phase-count = <4>;
phase0-gpio = <&pio PC 5 GPIO_ACTIVE_HIGH>;
phase1-gpio = <&pio PC 6 GPIO_ACTIVE_HIGH>;
phase2-gpio = <&pio PC 8 GPIO_ACTIVE_HIGH>;
phase3-gpio = <&pio PC 9 GPIO_ACTIVE_HIGH>;
step-resolution = <8>;
clockwise-sequence = /bits/ 8 <0x09 0x01 0x03 0x02 0x06 0x04 0x0c 0x08>;
counterclockwise-sequence = /bits/ 8 <0x08 0x0c 0x04 0x06 0x02 0x03 0x01 0x09>;
phase-delay-us = <5>;
step-delay-ms = <2>;
status = "okay";
};
Driver Implementation
Phase Control Function
static void apply_motor_phase(struct device *dev, int *gpio_pins,
int pin_count, uint8_t phase_pattern, int delay_us)
{
int pin_state;
for (int i = 0; i < pin_count; i++) {
pin_state = (phase_pattern >> i) & 0x01;
gpio_set_value(gpio_pins[i], pin_state);
udelay(delay_us);
}
}
Motor Stop Function
static void halt_motor(struct device *dev, int *gpio_pins, int pin_count)
{
for (int i = 0; i < pin_count; i++) {
gpio_set_value(gpio_pins[i], 0);
}
}
Step Execution Logic
static int execute_motor_steps(struct motor_driver *driver, struct movement_data *params)
{
uint8_t *phase_sequence;
switch (params->direction) {
case CLOCKWISE:
phase_sequence = driver->cw_sequence;
break;
case COUNTERCLOCKWISE:
phase_sequence = driver->ccw_sequence;
break;
default:
return -EINVAL;
}
for (int cycle = 0; cycle < params->step_count; cycle++) {
for (int phase = 0; phase < driver->step_resolution; phase++) {
apply_motor_phase(driver->dev, driver->phase_pins,
driver->phase_count, phase_sequence[phase],
driver->phase_delay);
mdelay(driver->step_delay);
}
}
halt_motor(driver->dev, driver->phase_pins, driver->phase_count);
return 0;
}
System Verification
Driver Initialization Check
Verify driver loading with dmesg:
dmesg | grep motor-control
Expected output includes phase configuration parameters and successful probe status.
Motor Control Testing
Execute clockwise rotation (100 steps):
echo 1,100 > /sys/devices/platform/focus_motor/motor_ctrl
Execute counterclockwise rotation (100 steps):
echo 2,100 > /sys/devices/platform/focus_motor/motor_ctrl