void graph_init (void) { uint8_t i; // read old days info from eeprom and if it look wrong, initialise it to zero eeprom_read_block ((void *) &PowerDays, (const void *) &eePowerDays, sizeof (PowerDays)); if (median_getSize(&PowerDays) != 20) { median_init(&PowerDays, 20); for (i = 0; i < 20; i++) median_add(&PowerDays, 0); eeprom_write_block ((const void *) &PowerDays, (void *) &eePowerDays, sizeof (PowerDays)); } // do the same with hours eeprom_read_block ((void *) &PowerHours, (const void *) &eePowerHours, sizeof (PowerHours)); if (median_getSize(&PowerHours) != 20) { median_init(&PowerHours, 20); for (i = 0; i < 20; i++) median_add(&PowerHours, 0); eeprom_write_block ((const void *) &PowerHours, (void *) &eePowerHours, sizeof (PowerHours)); } median_init(&PowerMins, 20); for (i = 0; i < 20; i++) { median_add(&PowerMins, 0); } lcd_remapChar (lcd_botquar, BOTQUAR); lcd_remapChar (lcd_bothalf, BOTHALF); lcd_remapChar (lcd_botthre, BOTTHRE); lcd_remapChar (lcd_topthre, TOPTHRE); lcd_remapChar (lcd_tophalf, TOPHALF); lcd_remapChar (lcd_topquar, TOPQUAR); lcd_remapChar (lcd_block, BLOCK); }
void rpm_init (void) { // Enable timer3 overflow interrupt TIMSK3 = BV (TOIE3); TCCR3A = 0; // not using output compare pins TCCR3B = BV (CS32); // Set Normal mode, CLK/256 prescaler DDRE &= ~BV (5); // port E5 as input (INT5) PORTE |= BV (5); // turn on pullup on E5 EICRB |= BV (ISC50) | BV (ISC51); // interrupt on rising edge EIMSK |= BV (INT5); // enable int 5 median_init (&RpmMedian, 10); minmax_init(&RpmHourMax, 60, true); }
CCM_FUNC static THD_FUNCTION(ThreadADC, arg) { (void)arg; chRegSetThreadName("Sensors"); adcsample_t * sensorsDataPtr; size_t n; uint16_t i, pos; uint32_t an[3] = {0, 0, 0}; median_t an1, an2, an3; uint8_t row, col; chThdSleepMilliseconds(250); timcapEnable(&TIMCAPD3); chVTSet(&vt_freqin, FREQIN_INTERVAL, freqinVTHandler, NULL); adcStartConversion(&ADCD1, &adcgrpcfg_sensors, samples_sensors, ADC_GRP1_BUF_DEPTH); median_init(&an1, 0 , an1_buffer, ADC_GRP1_BUF_DEPTH/2); median_init(&an2, 0 , an2_buffer, ADC_GRP1_BUF_DEPTH/2); median_init(&an3, 0 , an3_buffer, ADC_GRP1_BUF_DEPTH/2); while (TRUE) { while (!recvFreeSamples(&sensorsMb, (void*)&sensorsDataPtr, &n)) chThdSleepMilliseconds(5); an[0]= 0; an[1]= 0; an[2]= 0; /* Filtering and adding */ for (i = 0; i < (n/ADC_GRP1_NUM_CHANNELS); i++) { pos = i * ADC_GRP1_NUM_CHANNELS; an[0] += median_filter(&an1, sensorsDataPtr[pos]); an[1] += median_filter(&an2, sensorsDataPtr[pos+1]); an[2] += median_filter(&an3, sensorsDataPtr[pos+2]); } /* Averaging */ an[0] /= (n/ADC_GRP1_NUM_CHANNELS); an[1] /= (n/ADC_GRP1_NUM_CHANNELS); an[2] /= (n/ADC_GRP1_NUM_CHANNELS); /* Convert to milliVolts */ an[0] *= VBAT_RATIO; an[1] *= AN_RATIO; an[2] *= AN_RATIO; sensors_data.an1 = an[0]; sensors_data.an2 = an[1]; sensors_data.an3 = an[2]; /* Analog/Digital Sensors */ if (settings.sensorsInput == SENSORS_INPUT_DIRECT) { sensors_data.tps = calculateTpFromMillivolt(settings.tpsMinV, settings.tpsMaxV, sensors_data.an2); sensors_data.rpm = calculateFreqWithRatio(sensors_data.freq1, settings.rpmMult); sensors_data.spd = calculateFreqWithRatio(sensors_data.freq2, settings.spdMult); } else if (settings.sensorsInput == SENSORS_INPUT_TEST) { sensors_data.tps = rand16(0, 200); sensors_data.rpm = rand16(10, 18000); sensors_data.spd = rand16(5, 10000); } /* AFR */ if (settings.afrInput == AFR_INPUT_AN) { sensors_data.afr = calculateAFRFromMillivolt(settings.AfrMinVal, settings.AfrMaxVal, sensors_data.an3); } else if (settings.afrInput == AFR_INPUT_TEST) { sensors_data.afr = rand16(11000, 16000) / 100; } if (dbg_sensors) { chprintf(DBG_STREAM,"->[SENSORS] TPS mV/PCT: %06u/%04u\r\n", sensors_data.an2, sensors_data.tps); chprintf(DBG_STREAM,"->[SENSORS] RMP Hz/Mult/Val: %06u/%.4f/%04u\r\n", sensors_data.freq1, settings.rpmMult, sensors_data.rpm); chprintf(DBG_STREAM,"->[SENSORS] SPD Hz/Mult/Val: %06u/%.4f/%04u\r\n", sensors_data.freq2, settings.spdMult, sensors_data.spd); } if (findCell(sensors_data.tps/2, sensors_data.rpm, &row, &col)) { sensors_data.cell.row = row; sensors_data.cell.col = col; if (dbg_sensors) { chprintf(DBG_STREAM,"->[SENSORS] Row:Value/Col:Value: %02u:%05u/%02u:%05u\r\n", row, tableRows[row], col, tableColumns[col]*100); } if ((settings.functions & FUNC_RECORD) && sensors_data.rpm != 0) { /* Average */ tableAFR[row][col] = tableAFR[row][col] == 0 ? sensors_data.afr : ((uint16_t)sensors_data.afr+(uint16_t)tableAFR[row][col])/2; /* Peaks */ tableKnock[row][col] = sensors_data.knock_value > tableKnock[row][col] ? sensors_data.knock_value : tableKnock[row][col]; } } } return; }