Esempio n. 1
0
/*
 * Called every time new ADC values are available. Note that
 * the ADC is initialized from mcpwm.c
 */
void main_dma_adc_handler(void) {
    ledpwm_update_pwm();

    if (sample_at_start && (mc_interface_get_state() == MC_STATE_RUNNING ||
                            start_comm != mcpwm_get_comm_step())) {
        sample_now = 0;
        sample_ready = 0;
        sample_at_start = 0;
    }

    static int a = 0;
    if (!sample_ready) {
        a++;
        if (a >= sample_int) {
            a = 0;

            if (mc_interface_get_state() == MC_STATE_DETECTING) {
                curr0_samples[sample_now] = (int16_t)mcpwm_detect_currents[mcpwm_get_comm_step() - 1];
                curr1_samples[sample_now] = (int16_t)mcpwm_detect_currents_diff[mcpwm_get_comm_step() - 1];

                ph1_samples[sample_now] = (int16_t)mcpwm_detect_voltages[0];
                ph2_samples[sample_now] = (int16_t)mcpwm_detect_voltages[1];
                ph3_samples[sample_now] = (int16_t)mcpwm_detect_voltages[2];
            } else {
                curr0_samples[sample_now] = ADC_curr_norm_value[0];
                curr1_samples[sample_now] = ADC_curr_norm_value[1];

                ph1_samples[sample_now] = ADC_V_L1 - mcpwm_vzero;
                ph2_samples[sample_now] = ADC_V_L2 - mcpwm_vzero;
                ph3_samples[sample_now] = ADC_V_L3 - mcpwm_vzero;
            }

            vzero_samples[sample_now] = mcpwm_vzero;

            curr_fir_samples[sample_now] = (int16_t)(mc_interface_get_tot_current() * 100.0);
            f_sw_samples[sample_now] = (int16_t)(mc_interface_get_switching_frequency_now() / 10.0);

            status_samples[sample_now] = mcpwm_get_comm_step() | (mcpwm_read_hall_phase() << 3);

            sample_now++;

            if (sample_now == sample_len) {
                sample_ready = 1;
                sample_now = 0;
                chSysLockFromISR();
                chEvtSignalI(sample_send_tp, (eventmask_t) 1);
                chSysUnlockFromISR();
            }

            main_last_adc_duration = mcpwm_get_last_adc_isr_duration();
        }
    }
}
Esempio n. 2
0
File: main.c Progetto: likon/bldc
/*
 * Called every time new ADC values are available. Note that
 * the ADC is initialized from mcpwm.c
 */
void main_dma_adc_handler(void) {
	ledpwm_update_pwm();

	if (sample_at_start && mcpwm_get_state() == MC_STATE_STARTING) {
		sample_now = 0;
		sample_ready = 0;
		was_start_wample = 1;
		sample_at_start = 0;
	}

	static int a = 0;
	if (!sample_ready) {
		a++;
		if (a >= sample_int) {
			a = 0;
			curr0_samples[sample_now] = ADC_curr_norm_value[0];
			curr1_samples[sample_now] = ADC_curr_norm_value[1];
			ph1_samples[sample_now] = ADC_V_L1;
			ph2_samples[sample_now] = ADC_V_L2;
			ph3_samples[sample_now] = ADC_V_L3;
			vzero_samples[sample_now] = ADC_V_ZERO * MCPWM_VZERO_FACT;

			if (mcpwm_get_state() == MC_STATE_DETECTING && 0) {
				status_samples[sample_now] = mcpwm_get_detect_top();
			} else {
				uint8_t tmp;

				if (was_start_wample) {
					if (mcpwm_get_state() == MC_STATE_STARTING) {
						tmp = 1;
					} else if (mcpwm_get_state() == MC_STATE_RUNNING) {
						tmp = 2;
					} else {
						tmp = 3;
					}
				} else {
					tmp = mcpwm_read_hall_phase();
				}

				status_samples[sample_now] = mcpwm_get_comm_step() | (tmp << 3);
			}

			curr_fir_samples[sample_now] = (int16_t)(mcpwm_get_tot_current_filtered() * 100);

			sample_now++;

			if (sample_now == sample_len) {
				sample_ready = 1;
				sample_now = 0;
				was_start_wample = 0;
				chSysLockFromIsr();
				chEvtSignalI(sample_send_tp, (eventmask_t) 1);
				chSysUnlockFromIsr();
			}

			main_last_adc_duration = mcpwm_get_last_adc_isr_duration();
		}
	}
}
Esempio n. 3
0
void main_sample_print_data(bool at_start, uint16_t len, uint8_t decimation) {
    if (len > ADC_SAMPLE_MAX_LEN) {
        len = ADC_SAMPLE_MAX_LEN;
    }

    sample_len = len;
    sample_int = decimation;

    if (at_start) {
        sample_at_start = 1;
        start_comm = mcpwm_get_comm_step();
    } else {
        sample_now = 0;
        sample_ready = 0;
    }
}
Esempio n. 4
0
void mc_interface_fault_stop(mc_fault_code fault) {
	if (mc_interface_dccal_done() && m_fault_now == FAULT_CODE_NONE) {
		// Sent to terminal fault logger so that all faults and their conditions
		// can be printed for debugging.
		chSysLock();
		volatile int val_samp = TIM8->CCR1;
		volatile int current_samp = TIM1->CCR4;
		volatile int tim_top = TIM1->ARR;
		chSysUnlock();

		fault_data fdata;
		fdata.fault = fault;
		fdata.current = mc_interface_get_tot_current();
		fdata.current_filtered = mc_interface_get_tot_current_filtered();
		fdata.voltage = GET_INPUT_VOLTAGE();
		fdata.duty = mc_interface_get_duty_cycle_now();
		fdata.rpm = mc_interface_get_rpm();
		fdata.tacho = mc_interface_get_tachometer_value(false);
		fdata.cycles_running = m_cycles_running;
		fdata.tim_val_samp = val_samp;
		fdata.tim_current_samp = current_samp;
		fdata.tim_top = tim_top;
		fdata.comm_step = mcpwm_get_comm_step();
		fdata.temperature = NTC_TEMP(ADC_IND_TEMP_MOS1);
		terminal_add_fault_data(&fdata);
	}

	m_ignore_iterations = m_conf.m_fault_stop_time_ms;

	switch (m_conf.motor_type) {
	case MOTOR_TYPE_BLDC:
	case MOTOR_TYPE_DC:
		mcpwm_stop_pwm();
		break;

	case MOTOR_TYPE_FOC:
		mcpwm_foc_stop_pwm();
		break;

	default:
		break;
	}

	m_fault_now = fault;
}
Esempio n. 5
0
File: main.c Progetto: flv1991/bldc
void main_process_packet(unsigned char *data, unsigned char len) {
	if (!len) {
		return;
	}

	int16_t value16;
	int32_t value32;

	switch (data[0]) {
	case 1:
		// Sample and print data
		value16 = (int)data[1] << 8 | (int)data[2];
		if (value16 > ADC_SAMPLE_MAX_LEN) {
			value16 = ADC_SAMPLE_MAX_LEN;
		}
		sample_len = value16;
		sample_int = data[3];
		sample_now = 0;
		sample_ready = 0;
		break;

	case 2:
		// Duty Control
		value16 = (int)data[1] << 8 | (int)data[2];
		mcpwm_set_duty((float)value16 / 1000.0);
		break;

	case 3:
		// PID Control
		value32 = (int)data[1] << 24 | (int)data[2] << 16 | (int)data[3] << 8 | (int)data[4];
		mcpwm_set_pid_speed((float)value32);
		break;

	case 4:
		// Detect
		mcpwm_set_detect();
		break;

	case 5:
		// Reset Fault
		// TODO
		break;

	case 6:
		// Sample and print data at start
		value16 = (int)data[1] << 8 | (int)data[2];
		if (value16 > ADC_SAMPLE_MAX_LEN) {
			value16 = ADC_SAMPLE_MAX_LEN;
		}

		sample_len = value16;
		sample_int = data[3];
		sample_at_start = 1;
		start_comm = mcpwm_get_comm_step();
		break;

	case 7:
		// Current Control
		value16 = (int)data[1] << 8 | (int)data[2];
		mcpwm_set_current((float)value16 / 100.0);
		break;

	case 8:
		// Brake current control
		value16 = (int)data[1] << 8 | (int)data[2];
		mcpwm_set_brake_current((float)value16 / 100.0);
		break;

	default:
		break;
	}
}
Esempio n. 6
0
void mc_interface_mc_timer_isr(void) {
	ledpwm_update_pwm(); // LED PWM Driver update

	const float input_voltage = GET_INPUT_VOLTAGE();

	// Check for faults that should stop the motor
	static int wrong_voltage_iterations = 0;
	if (input_voltage < m_conf.l_min_vin ||
			input_voltage > m_conf.l_max_vin) {
		wrong_voltage_iterations++;

		if ((wrong_voltage_iterations >= 8)) {
			mc_interface_fault_stop(input_voltage < m_conf.l_min_vin ?
					FAULT_CODE_UNDER_VOLTAGE : FAULT_CODE_OVER_VOLTAGE);
		}
	} else {
		wrong_voltage_iterations = 0;
	}

	if (mc_interface_get_state() == MC_STATE_RUNNING) {
		m_cycles_running++;
	} else {
		m_cycles_running = 0;
	}

	if (pwn_done_func) {
		pwn_done_func();
	}

	const float current = mc_interface_get_tot_current_filtered();
	const float current_in = mc_interface_get_tot_current_in_filtered();
	m_motor_current_sum += current;
	m_input_current_sum += current_in;
	m_motor_current_iterations++;
	m_input_current_iterations++;

	float abs_current = mc_interface_get_tot_current();
	float abs_current_filtered = current;
	if (m_conf.motor_type == MOTOR_TYPE_FOC) {
		// TODO: Make this more general
		abs_current = mcpwm_foc_get_abs_motor_current();
		abs_current_filtered = mcpwm_foc_get_abs_motor_current_filtered();
	}

	// Current fault code
	if (m_conf.l_slow_abs_current) {
		if (fabsf(abs_current_filtered) > m_conf.l_abs_current_max) {
			mc_interface_fault_stop(FAULT_CODE_ABS_OVER_CURRENT);
		}
	} else {
		if (fabsf(abs_current) > m_conf.l_abs_current_max) {
			mc_interface_fault_stop(FAULT_CODE_ABS_OVER_CURRENT);
		}
	}

	// Watt and ah counters
	const float f_sw = mc_interface_get_switching_frequency_now();
	if (fabsf(current) > 1.0) {
		// Some extra filtering
		static float curr_diff_sum = 0.0;
		static float curr_diff_samples = 0;

		curr_diff_sum += current_in / f_sw;
		curr_diff_samples += 1.0 / f_sw;

		if (curr_diff_samples >= 0.01) {
			if (curr_diff_sum > 0.0) {
				m_amp_seconds += curr_diff_sum;
				m_watt_seconds += curr_diff_sum * input_voltage;
			} else {
				m_amp_seconds_charged -= curr_diff_sum;
				m_watt_seconds_charged -= curr_diff_sum * input_voltage;
			}

			curr_diff_samples = 0.0;
			curr_diff_sum = 0.0;
		}
	}

	// Sample collection
	if (m_sample_at_start && (mc_interface_get_state() == MC_STATE_RUNNING ||
			m_start_comm != mcpwm_get_comm_step())) {
		m_sample_now = 0;
		m_sample_ready = 0;
		m_sample_at_start = 0;
	}

	static int a = 0;
	if (!m_sample_ready) {
		a++;
		if (a >= m_sample_int) {
			a = 0;

			if (mc_interface_get_state() == MC_STATE_DETECTING) {
				m_curr0_samples[m_sample_now] = (int16_t)mcpwm_detect_currents[mcpwm_get_comm_step() - 1];
				m_curr1_samples[m_sample_now] = (int16_t)mcpwm_detect_currents_diff[mcpwm_get_comm_step() - 1];

				m_ph1_samples[m_sample_now] = (int16_t)mcpwm_detect_voltages[0];
				m_ph2_samples[m_sample_now] = (int16_t)mcpwm_detect_voltages[1];
				m_ph3_samples[m_sample_now] = (int16_t)mcpwm_detect_voltages[2];
			} else {
				m_curr0_samples[m_sample_now] = ADC_curr_norm_value[0];
				m_curr1_samples[m_sample_now] = ADC_curr_norm_value[1];

				m_ph1_samples[m_sample_now] = ADC_V_L1 - mcpwm_vzero;
				m_ph2_samples[m_sample_now] = ADC_V_L2 - mcpwm_vzero;
				m_ph3_samples[m_sample_now] = ADC_V_L3 - mcpwm_vzero;
			}

			m_vzero_samples[m_sample_now] = mcpwm_vzero;

			m_curr_fir_samples[m_sample_now] = (int16_t)(mc_interface_get_tot_current() * 100.0);
			m_f_sw_samples[m_sample_now] = (int16_t)(mc_interface_get_switching_frequency_now() / 10.0);

			m_status_samples[m_sample_now] = mcpwm_get_comm_step() | (mcpwm_read_hall_phase() << 3);

			m_sample_now++;

			if (m_sample_now == m_sample_len) {
				m_sample_ready = 1;
				m_sample_now = 0;
				chSysLockFromISR();
				chEvtSignalI(sample_send_tp, (eventmask_t) 1);
				chSysUnlockFromISR();
			}

			m_last_adc_duration_sample = mcpwm_get_last_adc_isr_duration();
		}
	}
}