Example #1
0
void motor_timer_set_absolute(uint64_t timestamp_hnsec)
{
	const uint64_t current_timestamp = motor_timer_hnsec();
	if (timestamp_hnsec > current_timestamp) {
		motor_timer_set_relative(timestamp_hnsec - current_timestamp);
	} else {
		motor_timer_set_relative(0);
	}
}
Example #2
0
void motor_rtctl_start(float duty_cycle, bool reverse)
{
    motor_rtctl_stop();                    // Just in case

    if (!_initialization_confirmed) {
        return; // Go home you're drunk
    }

    if (duty_cycle <= 0) {
        assert(0);
        return;
    }

    /*
     * Initialize the structs
     */
    memset(&_diag, 0, sizeof(_diag));
    memset(&_state, 0, sizeof(_state));    // Mighty reset

    motor_forced_rotation_detector_reset();

    _diag.started_at = motor_timer_hnsec();

    _state.comm_table = reverse ? COMMUTATION_TABLE_REVERSE : COMMUTATION_TABLE_FORWARD;

    _state.pwm_val_after_spinup = motor_pwm_compute_pwm_val(duty_cycle);

    init_adc_filters();

    /*
     * Initial spinup.
     */
    const tprio_t orig_priority = chThdSetPriority(HIGHPRIO);

    motor_pwm_prepare_to_start();

    const bool started = do_bemf_spinup(duty_cycle);

    /*
     * Engage the normal mode if started
     * At this point, if the spinup was OK, we're sutiated RIGHT AFTER THE DETECTED ZERO CROSS, engaged.
     */
    if (started) {
        _state.blank_time_deadline = motor_timer_hnsec() + _params.comm_blank_hnsec;
        _state.zc_detection_result = ZC_DETECTED;
        _state.flags = FLAG_ACTIVE | FLAG_SPINUP;
        motor_timer_set_relative(_state.comm_period / 3);
        lowsyslog("Motor: Spinup OK, comm period: %u usec\n", (unsigned)(_state.comm_period / HNSEC_PER_USEC));
    } else {
        lowsyslog("Motor: Spinup failed\n");
        motor_rtctl_stop();
    }

    chThdSetPriority(orig_priority);
}
Example #3
0
void motor_timer_callback(uint64_t timestamp_hnsec)
{
    if (!(_state.flags & FLAG_ACTIVE)) {
        return;
    }

    motor_timer_set_relative(_state.comm_period);

    // Next comm step
    _state.current_comm_step++;
    if (_state.current_comm_step >= MOTOR_NUM_COMMUTATION_STEPS) {
        _state.current_comm_step = 0;
    }

    bool stop_now = false;

    switch (_state.zc_detection_result) {
    case ZC_DETECTED: {
        engage_current_comm_step();
        register_good_step();
        _state.flags &= ~FLAG_SYNC_RECOVERY;
        break;
    }
    case ZC_DESATURATION: {
        engage_current_comm_step();
        fake_missed_zc_detection(timestamp_hnsec);
        _state.flags |= FLAG_SYNC_RECOVERY;
        _state.immediate_desaturations++;
        if (_state.immediate_desaturations >= _params.zc_failures_max) {
            stop_now = true;
        }
        break;
    }
    case ZC_NOT_DETECTED:
    case ZC_FAILED: {
        if ((_state.flags & FLAG_SPINUP) && !(_state.flags & FLAG_SYNC_RECOVERY)) {
            engage_current_comm_step();
        } else {
            motor_pwm_set_freewheeling();
        }
        fake_missed_zc_detection(timestamp_hnsec);
        register_bad_step(&stop_now);
        _state.flags |= FLAG_SYNC_RECOVERY;
        break;
    }
    default: {
        assert(0);
        stop_now = true;
    }
    }

    if (stop_now) {
        stop_from_isr(); // No bounce no play
        return;
    }

    _state.zc_detection_result = ZC_NOT_DETECTED;
    _state.blank_time_deadline = timestamp_hnsec + _params.comm_blank_hnsec;

    prepare_zc_detector_for_next_step();
    motor_adc_enable_from_isr();
}