void calibrate(const ComType com, const Calibrate *data) {
	__disable_irq();
	PIN_ENABLE.pio->PIO_SODR = PIN_ENABLE.mask;

	uint32_t tick_sum = 0;
	uint16_t tick_last = 0;
	for(uint16_t freq = 0; freq <= FREQUENCY_VALUE_SUM_MAX; freq+=8) {
		set_frequency(freq);
		SLEEP_MS(1);
		while(!(PIN_FEEDBACK.pio->PIO_PDSR & PIN_FEEDBACK.mask)) {
			__NOP();
		}
		while(PIN_FEEDBACK.pio->PIO_PDSR & PIN_FEEDBACK.mask) {
			__NOP();
		}
		tick_last = SysTick->VAL;
		SLEEP_US(1);
		while(!(PIN_FEEDBACK.pio->PIO_PDSR & PIN_FEEDBACK.mask)) {
			uint16_t tick_next = SysTick->VAL;
			if(tick_last < tick_next) {
				tick_sum += FEEDBACK_TICK_MAX - tick_next + tick_last;
			} else {
				tick_sum += tick_last - tick_next;
			}
			tick_last = tick_next;
		}

		SLEEP_US(1);

		do {
			uint16_t tick_next = SysTick->VAL;
			if(tick_last < tick_next) {
				tick_sum += FEEDBACK_TICK_MAX - tick_next + tick_last;
			} else {
				tick_sum += tick_last - tick_next;
			}
			tick_last = tick_next;
		} while(PIN_FEEDBACK.pio->PIO_PDSR & PIN_FEEDBACK.mask);

		uint16_t real_freq = (BOARD_MCK+tick_sum/2)/tick_sum;
		BC->frequency_match[freq/8] = real_freq;

		tick_sum = 0;
	}

	PIN_ENABLE.pio->PIO_CODR = PIN_ENABLE.mask;
	save_calibration();
	__enable_irq();

	CalibrateReturn cr;
	cr.header         = data->header;
	cr.header.length  = sizeof(CalibrateReturn);
	cr.calibration    = true;

	BA->send_blocking_with_timeout(&cr, sizeof(CalibrateReturn), com);
}
Example #2
0
static int itf_sd_run(long argc, unsigned long data)
{
	pkt_hdr *ph = NULL;
	Pkt rec;
	struct pktrec tmp;
	int i = 0;

	if (itf_sd_init() < 0) {
		itf_sd_exit();
		return -1;
	}

	while (ap_is_running()) {
		if (++i == 5000) {
			timer_mgr_run_timerlist(NULL, g_timer, 0, 0);
			i = 0;
		}
		if ((ph = ReadDbus()) == NULL) {
			SLEEP_US(5000);
			continue;
		}

		if ((pkthdr_get_type(ph) != PKTTYPE_CDR) &&
				(pkthdr_get_type(ph) != PKTTYPE_EVENT)) {
			LGWRERROR(ph, pkthdr_get_plen(ph), "Wrong cdr received, type %u, subtype %u.",
					pkthdr_get_type(ph), pkthdr_get_subtype(ph));
			free(ph);
			continue;
		}
		if ((pkthdr_get_subtype(ph) != PKTTYPE_CDR_BSSAP /* PKTTYPE_EVENT_BSSAP */) &&
				(pkthdr_get_subtype(ph) != PKTTYPE_CDR_IUCS /* PKTTYPE_EVENT_IUCS */)) {
			LGWRERROR(ph, pkthdr_get_plen(ph), "Wrong subtype of cdr/event");
			free(ph);
			continue;
		}
		if (rec.Decode((char *)ph, pkthdr_get_plen(ph)) < 0) {
			LGWRERROR(ph, pkthdr_get_plen(ph), "Failed to decode packet:");
			free(ph);
			continue;
		}

		++g_recieve_msg;
		tmp.rec = (Pkt *)&rec;
		pkthdr_set_sync(&(tmp.hdr));
		pkthdr_set_ts(&(tmp.hdr), rec.u32ReportTimeS, rec.u32ReportTimeNS);

		switch (rec.u8Type)
		{
		case PKTTYPE_CDR:
			if (rec.tdata.cdrbssap.u16LAC == 0) {
				std::map<unsigned int, unsigned int>::iterator it;

				it = ci2lac.find((unsigned int)rec.tdata.cdrbssap.u16CI);
				if (it != ci2lac.end()) {
					rec.tdata.cdrbssap.u16LAC = it->second;
					LOGDEBUG("LAC updated to %u for CI %u",
							it->second, it->first);
				}
				else {
					LOGDEBUG("LAC unknown for CI %u", rec.tdata.cdrbssap.u16CI);
				}
			}
			switch (rec.tdata.cdrbssap.u8CDRType) {
				case 1:
				case 2:
					/* 通话 */
					adapter_write(call_adap_to, &tmp, sizeof(rec));
					++g_call_msg;
					break;
				case 4:
				case 5:
					/* 开关机 */
					++g_power_msg;
					adapter_write(power_adap_to, &tmp, sizeof(rec));
					break;
				case 6:
				case 7:
					/* 正常/周期位置更新 */
					++g_location_msg;
					adapter_write(location_adap_to, &tmp, sizeof(rec));
					break;
				case 12:
				case 13:
					/* SMS */
					++g_sms_msg;
					adapter_write(sms_adap_to, &tmp, sizeof(rec));
					break;
			}
			break;

		case PKTTYPE_EVENT:
			if (rec.tdata.eventbssap.u16FromLAC == 0) {
				std::map<unsigned int, unsigned int>::iterator it;

				it = ci2lac.find((unsigned int)rec.tdata.eventbssap.u16ToCI);
				if (it != ci2lac.end()) {
					rec.tdata.eventbssap.u16FromLAC = it->second;
					LOGDEBUG("LAC updated to %u for CI %u",
							it->second, it->first);
				}
				else {
					LOGDEBUG("LAC unknown for CI %u", rec.tdata.eventbssap.u16ToCI);
				}
			}
			switch (rec.u8Protocol) {
				case 1:
				case 2:
					/* 内部切换事件及成功切出事件 */
					++g_switch_msg;
					adapter_write(switch_adap_to, &tmp, sizeof(rec));
					break;
				default:
					break;
			}
			break;

		default:
			LOGERROR("Unknown subtype %u", pkthdr_get_subtype(ph));
			break;
		}

		free(ph);
	}

	TimerCallback(0, 0, NULL, NULL);
	itf_sd_exit();
	return 0;
}