コード例 #1
0
ファイル: main.c プロジェクト: quark-mcu/qmsi
int main(void)
{
	qm_rtc_config_t rtc_cfg;
	unsigned int count = 0;
	/* loop_max : Maximum number of iterations.
	 * A value of 50 will run the application for roughly 30s.
	 */
	const unsigned int loop_max = 50;
	gpio_init();
	pin_mux_setup();
	gpio_set_out(BOARD_LED_PIN, 0); /* Configure the onboard LED pin. */

	/* Clear Screen. */
	QM_PUTS("Starting: Power Profiler");
	QM_PUTS("Low power mode example.");
	QM_PRINTF("Increment = %d\n", QM_RTC_ALARM_SECOND(CLK_RTC_DIV_1));

	clk_periph_enable(CLK_PERIPH_RTC_REGISTER | CLK_PERIPH_CLK);

	/* Initialise RTC configuration: Run, but don't interrupt. */
	rtc_cfg.init_val = 0;
	rtc_cfg.alarm_en = 0;
	rtc_cfg.alarm_val = QM_RTC_ALARM_SECOND(CLK_RTC_DIV_1);
	rtc_cfg.callback = rtc_example_callback;
	rtc_cfg.prescaler = CLK_RTC_DIV_1;
	qm_rtc_set_config(QM_RTC_0, &rtc_cfg);

	QM_IR_UNMASK_INT(QM_IRQ_RTC_0_INT);
	QM_IRQ_REQUEST(QM_IRQ_RTC_0_INT, qm_rtc_0_isr);

#if (!QM_SENSOR)
	test_clock_rates();
#endif

	/* Enable the RTC Interrupt. */
	rtc_cfg.alarm_en = 1;
	qm_rtc_set_config(QM_RTC_0, &rtc_cfg);

	count = 0;
	while (++count < loop_max) {
		QM_PRINTF("\nC:%d R:%d => ", count, rtc_tick);

		slow_mode_test();
		halt_test();
		core_sleep_test();
		/* TODO : Enable soc_sleep test for c1000. */
		soc_sleep_test();
		/* TODO : Enable soc_deep_sleep test for d2000 and c1000. */
		soc_deep_sleep_test();
	}
	SOC_WATCH_TRIGGER_FLUSH();
	QM_PUTS("Finished: Power Profiler");
	return 0;
}
コード例 #2
0
ファイル: main.c プロジェクト: quark-mcu/qmsi
void start_rtc()
{
	uint32_t aonc_start;
	qm_rtc_config_t cfg;

	/* Make sure RTC is enabled during sleep. */
	QM_SCSS_PMU->slp_cfg &= ~QM_SCSS_SLP_CFG_RTC_DIS;

	cfg.init_val = 0;
	cfg.alarm_en = true;
	cfg.alarm_val = RTC_ALARM_SECONDS(2);
	cfg.prescaler = RTC_PRESCALER;
	cfg.callback = NULL;
	cfg.callback_data = NULL;

	QM_IR_UNMASK_INT(QM_IRQ_RTC_0_INT);
	QM_IRQ_REQUEST(QM_IRQ_RTC_0_INT, qm_rtc_0_isr);
	qm_rtc_set_config(QM_RTC_0, &cfg);

	/*
	 * The RTC clock resides in a different clock domain
	 * to the system clock.
	 * It takes 3-4 RTC ticks for a system clock write to propagate
	 * to the RTC domain.
	 * If an entry to sleep is initiated without waiting for the
	 * transaction to complete the SOC will not wake from sleep.
	 */
	aonc_start = QM_AONC[0]->aonc_cnt;
	while (QM_AONC[0]->aonc_cnt - aonc_start < RTC_SYNC_CLK_COUNT) {
	}
}
コード例 #3
0
ファイル: main.c プロジェクト: jeez/qmsi
int main(void)
{
	qm_rtc_config_t rtc_cfg;
	unsigned int count = 0;
	/* Maximum number of 3-second iterations. */
	const unsigned int loop_max = 5;
	gpio_init();
	gpio_set_out(BOARD_LED_PIN, 0); /* Configure the onboard LED pin. */

	/* Clear Screen. */
	QM_PUTS("Starting: Power Profiler");
	QM_PUTS("Low power mode example.");
	QM_PRINTF("Increment = %d\n", QM_RTC_ALARM_SECOND(CLK_RTC_DIV_1));

	clk_periph_enable(CLK_PERIPH_RTC_REGISTER | CLK_PERIPH_CLK);

	/* Initialise RTC configuration: Run, but don't interrupt. */
	rtc_cfg.init_val = 0;
	rtc_cfg.alarm_en = 0;
	rtc_cfg.alarm_val = QM_RTC_ALARM_SECOND(CLK_RTC_DIV_1);
	rtc_cfg.callback = rtc_example_callback;
	rtc_cfg.prescaler = CLK_RTC_DIV_1;
	qm_rtc_set_config(QM_RTC_0, &rtc_cfg);

	qm_irq_request(QM_IRQ_RTC_0_INT, qm_rtc_0_isr);

	test_clock_rates();

	/* Enable the RTC Interrupt. */
	rtc_cfg.alarm_en = 1;
	qm_rtc_set_config(QM_RTC_0, &rtc_cfg);

	count = 0;
	while (++count < loop_max) {
		QM_PRINTF("\nC:%d R:%d => ", count, rtc_tick);

		slow_mode_test();
		halt_test();
		sleep_test();
#if DEEP_SLEEP
		deep_sleep_test();
#endif
	}
	QM_PUTS("Finished: Power Profiler");
	return 0;
}
コード例 #4
0
ファイル: xmodem_io_uart.c プロジェクト: Hlotfy/qmsi
/* Receive one byte */
int xmodem_io_getc(uint8_t *ch)
{
	enum rx_state retv;

	/* Set up timeout timer */
	rtc_cfg.alarm_en = true;
	qm_rtc_set_config(QM_RTC_0, &rtc_cfg);

	/* Reseting the state and read byte */
	xmodem_io_rx_state = STATE_WAITING;
	qm_uart_irq_read(DM_CONFIG_UART, &uart_transfer);

	/* Wait for UART interruption or RTC timeout callback */
	while (retv = xmodem_io_rx_state, retv == STATE_WAITING) {
		; /* Busy wait until one of the callbacks is called */
	}
	switch (retv) {
	case STATE_TIMEOUT:
		qm_uart_irq_read_terminate(DM_CONFIG_UART);
		break;
	case STATE_UART_RX_DONE:
		/* Got byte */
		*ch = in_byte;
		break;
	default:
		/**
		 * Handle STATE_UART_ERROR case which can happen on UART read
		 * error, and STATE_WAITING which is an impossible case
		 */
		break;
	}

	/* Disable timer alarm */
	rtc_cfg.alarm_en = false;
	qm_rtc_set_config(QM_RTC_0, &rtc_cfg);

	return retv;
}
コード例 #5
0
static int rtc_qmsi_set_alarm(struct device *dev, u8_t chan_id,
				const struct counter_alarm_cfg *alarm_cfg)
{
	qm_rtc_config_t qm_cfg;
	int result = 0;

	qm_cfg.init_val = 0;
	qm_cfg.alarm_en = 1;
	qm_cfg.alarm_val = alarm_cfg->ticks;

	user_cb = alarm_cfg->callback;
	/* Casting callback type due different input parameter from QMSI
	 * compared aganst the Zephyr callback from void cb(struct device *dev)
	 * to void cb(void *)
	 */
	qm_cfg.callback = rtc_callback;
	qm_cfg.callback_data = (void *)alarm_cfg;

	/* Set prescaler value. Ideally, the divider should come from struct
	 * rtc_config instead. It's safe to use RTC_DIVIDER here for now since
	 * values defined by clk_rtc_div and by QMSI's clk_rtc_div_t match for
	 * both D2000 and SE.
	 */
	qm_cfg.prescaler = (clk_rtc_div_t)CONFIG_RTC_PRESCALER - 1;

	if (IS_ENABLED(CONFIG_RTC_QMSI_API_REENTRANCY)) {
		k_sem_take(RP_GET(dev), K_FOREVER);
	}

	if (qm_rtc_set_config(QM_RTC_0, &qm_cfg)) {
		result = -EIO;
	}

	if (IS_ENABLED(CONFIG_RTC_QMSI_API_REENTRANCY)) {
		k_sem_give(RP_GET(dev));
	}

	k_busy_wait(60);

	qm_rtc_set_alarm(QM_RTC_0, alarm_cfg->ticks);

	return result;
}
コード例 #6
0
ファイル: xmodem_io_uart.c プロジェクト: Hlotfy/qmsi
/*-------------------------------------------------------------------------*/
void xmodem_io_uart_init()
{
	/* Pinmux for UART_x */
	qm_pmux_select(DM_COMM_UART_PIN_TX_ID, DM_COMM_UART_PIN_TX_FN);
	qm_pmux_select(DM_COMM_UART_PIN_RX_ID, DM_COMM_UART_PIN_RX_FN);
	qm_pmux_input_en(DM_COMM_UART_PIN_RX_ID, true);

	/* Enable UART and RTC clocks */
	clk_periph_enable(DM_COMM_UART_CLK | CLK_PERIPH_RTC_REGISTER |
			  CLK_PERIPH_CLK);

	/* Setup UART */
	qm_uart_set_config(DM_CONFIG_UART, &uart_config);

	/* Request IRQ for UART */
	dm_comm_irq_request();

	/* Set up timeout timer (RTC) */
	qm_irq_request(QM_IRQ_RTC_0, qm_rtc_isr_0);
	qm_rtc_set_config(QM_RTC_0, &rtc_cfg);
}
コード例 #7
0
ファイル: main.c プロジェクト: CurieBSP/qmsi
int main(void)
{
	qm_rtc_config_t rtc;

	QM_PUTS("Accelerometer example app\n");

	rtc.init_val = 0;
	rtc.alarm_en = true;
	rtc.alarm_val = ALARM;
	rtc.callback = print_accel_callback;

	qm_irq_request(QM_IRQ_RTC_0, qm_rtc_isr_0);

	clk_periph_enable(CLK_PERIPH_RTC_REGISTER | CLK_PERIPH_CLK);

	bmc150_init(BMC150_J14_POS_0);

	bmc150_set_accel_mode(BMC150_MODE_2G);
	bmc150_set_bandwidth(BMC150_BANDWIDTH_64MS);

	qm_rtc_set_config(QM_RTC_0, &rtc);

	return 0;
}
コード例 #8
0
ファイル: main.c プロジェクト: CurieBSP/qmsi
/* Low power app example */
int main(void)
{
	/* Setup the RTC to get out of sleep mode. deep sleep will require an */
	/* analog comparator interrupt to wake up the system. */
	/*  Variables */
	uint32_t pmux_sel_save[2], pmux_in_en_save, pmux_pullup_save;
	qm_ac_config_t ac_cfg;
	qm_rtc_config_t rtc_cfg;

	QM_PUTS("Low power mode example.");

	clk_periph_enable(CLK_PERIPH_RTC_REGISTER | CLK_PERIPH_CLK);

	/*  Initialise RTC configuration. */
	rtc_cfg.init_val = 0;
	rtc_cfg.alarm_en = 1;
	rtc_cfg.alarm_val = QM_RTC_ALARM_SECOND;
	rtc_cfg.callback = rtc_example_callback;
	qm_rtc_set_config(QM_RTC_0, &rtc_cfg);

	qm_irq_request(QM_IRQ_RTC_0, qm_rtc_isr_0);

	QM_PUTS("CPU Halt.");
	/* Halt the CPU, RTC alarm will wake me up. */
	cpu_halt();
	QM_PUTS("CPU Halt wakeup.");

	/* Set another alarm one minute from now. */
	qm_rtc_set_alarm(QM_RTC_0,
			 QM_RTC[QM_RTC_0].rtc_ccvr + QM_RTC_ALARM_SECOND);
	QM_PUTS("Go to sleep.");
	/* Go to sleep, RTC will wake me up. */
	soc_sleep();
	QM_PUTS("Wake up from sleep.");

	/* Physical step at this stage to raise the V on the comparator pin. */
	/* Go to deep sleep, a comparator should wake me up. */
	QM_PUTS("Go to deep sleep.");

	ac_cfg.reference =
	    BIT(WAKEUP_COMPARATOR_PIN); /* Ref internal voltage */
	ac_cfg.polarity = 0x0; /* Fire if greater than ref (high level) */
	ac_cfg.power = BIT(WAKEUP_COMPARATOR_PIN);  /* Normal operation mode */
	ac_cfg.int_en = BIT(WAKEUP_COMPARATOR_PIN); /* Enable comparator */
	ac_cfg.callback = ac_example_callback;
	qm_ac_set_config(&ac_cfg);

	qm_irq_request(QM_IRQ_AC, qm_ac_isr);

	/*
	 * Comparator pin will fire an interrupt when the input voltage is
	 * greater than the reference voltage (0.95V).
	 */

	/*
	 * In order to minimise power, pmux_sel must be set to 0, input enable
	 * must be cleared for any pins not expecting to be used to wake the
	 * SoC from deep sleep mode, in this example we are using AC 6.
	 */
	pmux_sel_save[0] = QM_SCSS_PMUX->pmux_sel[0];
	pmux_sel_save[1] = QM_SCSS_PMUX->pmux_sel[1];
	pmux_in_en_save = QM_SCSS_PMUX->pmux_in_en[0];

	pmux_pullup_save = QM_SCSS_PMUX->pmux_pullup[0];

	QM_SCSS_PMUX->pmux_sel[0] = QM_SCSS_PMUX->pmux_sel[1] = 0;
	QM_SCSS_PMUX->pmux_in_en[0] = BIT(WAKEUP_COMPARATOR_PIN);
	QM_SCSS_PMUX->pmux_pullup[0] = 0;

	/* Mux out comparator */
	qm_pmux_select(QM_PIN_ID_6, QM_PMUX_FN_1);
	qm_pmux_input_en(QM_PIN_ID_6, true);

	soc_deep_sleep();

	/* Restore previous pinmuxing settings. */
	QM_SCSS_PMUX->pmux_sel[0] = pmux_sel_save[0];
	QM_SCSS_PMUX->pmux_sel[1] = pmux_sel_save[1];
	QM_SCSS_PMUX->pmux_in_en[0] = pmux_in_en_save;
	QM_SCSS_PMUX->pmux_pullup[0] = pmux_pullup_save;

	QM_PUTS("Wake up from deep sleep.");
	return 0;
}
コード例 #9
0
ファイル: main.c プロジェクト: quark-mcu/qmsi
int main(void)
{
	qm_rtc_config_t rtc_cfg;
	uint32_t aonc_start;
	uint32_t rtc_trigger;

	/*  Initialise RTC configuration. */
	rtc_cfg.init_val = 0; /* Set initial value to 0. */
	rtc_cfg.alarm_en = 1; /* Enable alarm. */
	rtc_cfg.alarm_val = QM_RTC_ALARM_SECOND(CLK_RTC_DIV_1); /* 1s alarm. */
	rtc_cfg.callback = NULL;
	rtc_cfg.callback_data = NULL;
	rtc_cfg.prescaler = CLK_RTC_DIV_1;
	qm_rtc_set_config(QM_RTC_0, &rtc_cfg);

	/*
	 * The RTC clock resides in a different clock domain
	 * to the system clock.
	 * It takes 3-4 RTC ticks for a system clock write to propagate
	 * to the RTC domain.
	 * If an entry to sleep is initiated without waiting for the
	 * transaction to complete the SOC will not wake from sleep.
	 */
	aonc_start = QM_AONC[QM_AONC_0]->aonc_cnt;
	while (QM_AONC[QM_AONC_0]->aonc_cnt - aonc_start < RTC_SYNC_CLK_COUNT) {
	}

	QM_IR_UNMASK_INT(QM_IRQ_RTC_0_INT);
	QM_IRQ_REQUEST(QM_IRQ_RTC_0_INT, qm_rtc_0_isr);

	/*
	 * Enable LPSS by the Sensor Subsystem.
	 * This will clock gate sensor peripherals.
	 */
	qm_ss_power_soc_lpss_enable();

	/*
	 * Signal to the x86 core that the Sensor Subsystem
	 * is ready to enter LPSS mode.
	 */
	QM_SCSS_GP->gps2 |= QM_SCSS_GP_SENSOR_READY;

	rtc_trigger = switch_rtc_to_level();

	/* Go to LPSS, RTC will wake the Sensor Subsystem up. */
	qm_ss_power_cpu_ss2();

	/* Log the interrupt event in soc_watch. */
	SOC_WATCH_LOG_EVENT(SOCW_EVENT_INTERRUPT, QM_IRQ_RTC_0_INT_VECTOR);

	restore_rtc_trigger(rtc_trigger);

	/* Clear the SENSOR_READY flag in General Purpose Sticky Register 2. */
	QM_SCSS_GP->gps2 &= ~QM_SCSS_GP_SENSOR_READY;

	/*
	 * Disable LPSS.
	 * This will restore clock gating of sensor peripherals.
	 */
	qm_ss_power_soc_lpss_disable();

	/* Core still in C2 mode. */
	qm_gpio_clear_pin(QM_GPIO_0, PIN_OUT);
	clk_sys_udelay(GPIO_TOGGLE_DELAY);
	qm_gpio_set_pin(QM_GPIO_0, PIN_OUT);
	clk_sys_udelay(GPIO_TOGGLE_DELAY);
	qm_gpio_clear_pin(QM_GPIO_0, PIN_OUT);

	/* Set another alarm 1 second from now. */
	qm_rtc_set_alarm(QM_RTC_0, QM_RTC[QM_RTC_0]->rtc_ccvr +
				       (QM_RTC_ALARM_SECOND(CLK_RTC_DIV_1)));
	/*
	 * The RTC clock resides in a different clock domain
	 * to the system clock.
	 * It takes 3-4 RTC ticks for a system clock write to propagate
	 * to the RTC domain.
	 * If an entry to sleep is initiated without waiting for the
	 * transaction to complete the SOC will not wake from sleep.
	 */
	aonc_start = QM_AONC[QM_AONC_0]->aonc_cnt;
	while (QM_AONC[QM_AONC_0]->aonc_cnt - aonc_start < RTC_SYNC_CLK_COUNT) {
	}

	/*
	 * Enable LPSS by the Sensor Subsystem.
	 * This will clock gate sensor peripherals.
	 */
	qm_ss_power_soc_lpss_enable();

	/*
	 * Signal to the x86 core that the Sensor Subsystem
	 * is ready to enter LPSS mode.
	 */
	QM_SCSS_GP->gps2 |= QM_SCSS_GP_SENSOR_READY;

	rtc_trigger = switch_rtc_to_level();

	/* Go to LPSS, RTC will wake the Sensor Subsystem up. */
	qm_ss_power_cpu_ss2();

	/* Log the interrupt event in soc_watch. */
	SOC_WATCH_LOG_EVENT(SOCW_EVENT_INTERRUPT, QM_IRQ_RTC_0_INT_VECTOR);
	restore_rtc_trigger(rtc_trigger);

	/* Clear the SENSOR_READY flag in General Purpose Sticky Register 2. */
	QM_SCSS_GP->gps2 &= ~QM_SCSS_GP_SENSOR_READY;

	/*
	 * Disable LPSS.
	 * This will restore clock gating of sensor peripherals.
	 */
	qm_ss_power_soc_lpss_disable();

	/* Core still in C2LP mode. */
	qm_gpio_clear_pin(QM_GPIO_0, PIN_OUT);
	clk_sys_udelay(GPIO_TOGGLE_DELAY);
	qm_gpio_set_pin(QM_GPIO_0, PIN_OUT);
	clk_sys_udelay(GPIO_TOGGLE_DELAY);
	qm_gpio_clear_pin(QM_GPIO_0, PIN_OUT);

	/* Trigger soc_watch flush. */
	SOC_WATCH_TRIGGER_FLUSH();

	return 0;
}