示例#1
0
文件: lcd.c 项目: Micha500/gt3b
// send cnt bits to LCD controller, only low bits of "bits" are used
// use timer4 to get 600kHz clock for driving WR/ signal
// timer is used in one-pulse mode and is started after each WR/ change,
//   so there will always be minimal required length of pulse also
//   when interrupted by some interrupt
static void lcd_send_bits(u8 cnt, u16 bits) {
    // shift bits to high-bits
    bits <<= (u8)(16 - cnt);
    WR0;
    BSET(TIM4_CR1, 0);			// start timer
    WR0;				// optimize hack
    do {
	if (bits & 0x8000) {
	    DATA1;
	}
	else {
	    DATA0;
	}
	bits <<= 1;			// to next bit
	while (!BCHK(TIM4_SR, 0));	// wait for timer
	WR1;
	BRES(TIM4_SR, 0);		// clear intr flag
	BSET(TIM4_CR1, 0);		// start timer
	if (!--cnt)  break;
	while (!BCHK(TIM4_SR, 0));	// wait for timer
	WR0;
	BRES(TIM4_SR, 0);		// clear intr flag
	BSET(TIM4_CR1, 0);		// start timer
    } while (1);
    while (!BCHK(TIM4_SR, 0));		// wait for timer
    BRES(TIM4_SR, 0);			// clear intr flag
}
示例#2
0
文件: ppm.c 项目: eknl/gt3b
/*
    TIM3 overflow interrupt
    set next prescaler, output compare and overflow values to
      preload registers
*/
@interrupt void ppm_interrupt(void) {
    BRES(TIM3_SR1, 0);	// erase interrupt flag

    if (ppm_channel2) {
	if (ppm_channel2 == 2) {
	    // will be setting channel1 servo, so we are now generating
	    // SYNC signal in HW
	    // wakeup CALC task to compute new PPM values
	    // values for ARR registers will be updated after calculate done
	    // (and when we are still generating SYNC pulse)
	    awake(CALC);
	}
	// set servo channel
	TIM3_PSCR = PPM_PSC_SERVO;
	TIM3_CCR2H = hi8(PPM_300US_SERVO);
	TIM3_CCR2L = lo8(PPM_300US_SERVO);
	TIM3_ARRH = ppm_values[ppm_channel2];
	ppm_channel2++;
	TIM3_ARRL = ppm_values[ppm_channel2];
	if (++ppm_channel2 > channels2) {
	    // next to SYNC pulse
	    ppm_channel2 = 0;
	}
	return;
    }

    // set SYNC signal
    TIM3_PSCR = PPM_PSC_SYNC;
    TIM3_CCR2H = hi8(PPM_300US_SYNC);
    TIM3_CCR2L = lo8(PPM_300US_SYNC);
    TIM3_ARRH = ppm_values[0];
    TIM3_ARRL = ppm_values[1];
    ppm_channel2 = 2;  // to first channel (step 2 bytes)
}
示例#3
0
文件: input.c 项目: eknl/gt3b
static void read_ADC(void) {
    u16 *buf = adc_buffer[adc_buffer_pos];
    u8  dead;

    ADC_NEWVAL(0);
    ADC_NEWVAL(1);
    ADC_NEWVAL(2);
    adc_battery_last = ADC_DB3R;

    adc_buffer_pos++;
    adc_buffer_pos &= 3;

    BRES(ADC_CSR, 7);		// remove EOC flag
    BSET(ADC_CR1, 0);		// start new conversion

    // average battery voltage and check battery low
    // ignore very low, which means that it is supplied from SWIM connector
    adc_battery_filt = adc_battery_filt * (ADC_BAT_FILT - 1); // splitted - compiler hack
    adc_battery_filt = (adc_battery_filt + (ADC_BAT_FILT / 2)) / ADC_BAT_FILT
		       + adc_battery_last;
    adc_battery = (u16)((adc_battery_filt + (ADC_BAT_FILT / 2)) / ADC_BAT_FILT);
    // start checking battery after 5s from power on
    if (time_sec >= 5) {
	// wakeup task only when something changed
	if (adc_battery > 50 && adc_battery < battery_low_raw) {
	    // bat low
	    if (!menu_battery_low) {
		menu_battery_low = 1;
		awake(MENU);
	    }
	}
	else {
	    // bat OK, but apply some hysteresis to not switch quickly ON/OFF
	    if (menu_battery_low && adc_battery > battery_low_raw + 100) {
		menu_battery_low = 0;
		awake(MENU);
	    }
	}
    }

    // wakeup MENU task when showing battery or at calibrate
    if (menu_wants_adc)
	awake(MENU);

    // reset inactivity timer when some steering or throttle applied
    dead = cg.steering_dead_zone;
    if (dead < 20)  dead = 20;  // use some minimal dead zone for this check
    if (adc_steering_last < (cg.calib_steering_mid - dead) ||
        adc_steering_last > (cg.calib_steering_mid + dead))
	    reset_inactivity_timer();
    else {
	dead = cg.throttle_dead_zone;
	if (dead < 20)  dead = 20;  // use some minimal dead zone for this check
	if (adc_throttle_last < (cg.calib_throttle_mid - dead) ||
	    adc_throttle_last > (cg.calib_throttle_mid + dead))
		reset_inactivity_timer();
    }
}
示例#4
0
文件: ppm.c 项目: eknl/gt3b
// set number of channels
void ppm_set_channels(u8 n) {
    // disable PPM generation till new values will not be set
    ppm_enabled = 0;
    BRES(TIM3_CR1, 0);	// disable timer
    BSET(PD_ODR, 0);	// set PPM pin to 1

    // start with generating 20ms SYNC signal
    TIM3_CCR2H = hi8(PPM_300US_SYNC);
    TIM3_CCR2L = hi8(PPM_300US_SYNC);
    TIM3_ARRH = hi8(PPM_MUL_SYNC * 20);
    TIM3_ARRL = lo8(PPM_MUL_SYNC * 20);

    channels = n;
    channels2 = (u8)(n << 1);  // also 2* value for compare in ppm_interrupt
}