예제 #1
0
int main (void)
{
	uint8_t menu_status;
	struct keyboard_event input;

	static usart_rs232_options_t SERIAL_OPTIONS = {
		.baudrate = 57600,
		.charlength = USART_CHSIZE_8BIT_gc,
		.paritytype = USART_PMODE_DISABLED_gc,
		.stopbits = false
	};

	sysclk_init();	
	board_init();
	solenoid_init();
	gfx_mono_init();
	usart_init_rs232(USART_SERIAL, &SERIAL_OPTIONS);

	gpio_toggle_pin(NHD_C12832A1Z_BACKLIGHT);

	while(true) 
	{
		gfx_mono_menu_init(&main_menu);

		do {
			do {
				keyboard_get_key_state(&input);
			} while (input.type != KEYBOARD_RELEASE);

			menu_status = gfx_mono_menu_process_key(&main_menu, input.keycode);
		} while (menu_status == GFX_MONO_MENU_EVENT_IDLE);

		//Determine what song to play based on 
		//the input from the user controlling the A3BU
		switch(menu_status) {
			case 0:
				song_menu(0);
				play_song_with_input(SAMPLE_SONG, SAMPLE_SONG_LENGTH);
				break;
			case 1:
				song_menu(1);
				play_song_with_input(STAIRWAY, 6);
				break;
			case 2:
				song_menu(2);
				play_song_with_input(MISERLOU, 1);
				break;
			case 3:
				song_menu(3);
				play_serial();
				break;
		}
	}
}
예제 #2
0
/**
 * \brief Show a menu presenting the date and time applications
 */
void date_time_application(void)
{
    uint8_t menu_status;
    struct keyboard_event input;

    while(true) {
        gfx_mono_menu_init(&datetime_menu);
        do {
            do {
                keyboard_get_key_state(&input);
                // Wait for key release
            } while (input.type != KEYBOARD_RELEASE);

            // Send key to menu system
            menu_status = gfx_mono_menu_process_key(&datetime_menu,
                                                    input.keycode);
            // Wait for something useful to happen in the menu system
        } while (menu_status == GFX_MONO_MENU_EVENT_IDLE);

        switch(menu_status) {
        case 0:
            display_date_time_application();
            break;
        case 1:
            set_date_application();
            break;
        case 2:
            set_time_application();
            break;
        case 3:
            timezone_select_application();
            break;
        default:
            // Return to the main menu on unknown element or back key
            return;
        }
    }
}
예제 #3
0
/**
 * \brief Main function.
 *
 * Initializes the board and reads out the production date stored in EEPROM and
 * set timezone from EEPROM if it is set. If it is not set it will open the
 * timezone selector to select the local timezone. It then runs the menu system
 * in an infinite while loop.
 */
int main(void)
{
	uint8_t menu_status;
	struct keyboard_event input;
	uint32_t rtc_timestamp;

	sysclk_init();
	board_init();
	pmic_init();
	gfx_mono_init();
	touch_init();
	adc_sensors_init();

	// Enable display backlight
	gpio_set_pin_high(NHD_C12832A1Z_BACKLIGHT);

	// Workaround for known issue: Enable RTC32 sysclk
	sysclk_enable_module(SYSCLK_PORT_GEN, SYSCLK_RTC);
	while (RTC32.SYNCCTRL & RTC32_SYNCBUSY_bm) {
		// Wait for RTC32 sysclk to become stable
	}

	// If we have battery power and RTC is running, don't initialize RTC32
	if (rtc_vbat_system_check(false) != VBAT_STATUS_OK) {
		rtc_init();

		// Set current time to after production date
		rtc_timestamp = production_date_get_timestamp() + 1;
		rtc_set_time(rtc_timestamp);
	}

	// Get current time
	rtc_timestamp = rtc_get_time();
	// Make sure RTC has not been set to a too early date .
	if (rtc_timestamp < FIRST_POSSIBLE_TIMESTAMP) {
		// Set time to 01.01.2011 00:00:00
		rtc_set_time(FIRST_POSSIBLE_TIMESTAMP);
	}

	// Initialize USB CDC class
	cdc_start();

	cpu_irq_enable();

	// Display a splash screen showing button functions
	button_splash();

	// Set timezone from EEPROM or to a default value
	timezone_init();

	/* Main loop. Read keyboard status and pass input to menu system.
	 * When an element has been selected in the menu, it will return the
	 * index of the element that should be run. This can be an application
	 * or another menu.
	 */
	while (true) {

		// (re)initialize menu system
		gfx_mono_menu_init(&main_menu);

		do {
			do {
				keyboard_get_key_state(&input);
			// Wait for key release
			} while (input.type != KEYBOARD_RELEASE);

			// Send key to menu system
			menu_status = gfx_mono_menu_process_key(&main_menu, input.keycode);
		// Wait for something useful to happen in the menu system
		} while (menu_status == GFX_MONO_MENU_EVENT_IDLE);

		switch (menu_status) {
		case 0:
			ntc_sensor_application();
			break;
		case 1:
			lightsensor_application();
			break;
		case 2:
			production_date_application();
			break;
		case 3:
			date_time_application();
			break;
		case 4:
			// Toggle LCD Backlight
			gpio_toggle_pin(NHD_C12832A1Z_BACKLIGHT);
			break;
		case GFX_MONO_MENU_EVENT_EXIT:
			// Fall trough to default and show button splash
		default:
			button_splash();
			break;
		};
	}
}
예제 #4
0
/**
 * \brief Show menu for error insertion and handle user's selection.
 *
 * This function changes device configurations and does some hacks to make
 * the device behave incorrectly.
 *
 * The menu entries are
 *   - Change clock frequency: Changes the peripheral clock divider, simulating
 *     that the clock system has malfunctioned. This should be detected by the
 *     Class B frequency consistency test.
 *
 *   - Mess with test timer: Changes how often periodic tests are performed,
 *     simulating an error with an interrupt timer. This should be detected by
 *     the Class B interrupt monitor.
 *
 *   - Change a Flash section: Changes the string for the menu title stored in
 *     program memory to "Out of cheese", simulating Flash memory corruption.
 *     This can be changed back by selecting the menu item again. This should be
 *     detected by the Class B Flash CRC test.
 *
 *   - Scramble SRAM section: Starts a continuous DMA transfer in the background
 *     to a memory location, simulating transient SRAM corruption. This should
 *     be detected by the periodic and power-on Class B SRAM test.
 *
 *   - Enter infinite loop: Simulates a runaway program counter by looping
 *     forever. This should be detected by the watchdog timer system which is
 *     tested on device power-up.
 *
 *   - Change ADC reference: Enables a callback function for the ADC, which will
 *     change the voltage reference after the next completed conversion. This
 *     will cause the analog IO test to fail when user turns up the power to the
 *     plate.
 */
void oven_classb_error_insertion(void)
{
	uint8_t menu_status;
	struct keyboard_event input;
	struct adc_channel_config adcch_conf;

	/* Initialize menu system */
	gfx_mono_menu_init(&error_menu);

	/* Wait for user to select something in the menu system */
	do {
		do {
			keyboard_get_key_state(&input);
			oven_wdt_periodic_reset();
			/* Wait for key release */
		} while (input.type != KEYBOARD_RELEASE);

		/* Send key to menu system */
		menu_status = gfx_mono_menu_process_key(&error_menu,
				input.keycode);

		oven_wdt_periodic_reset();
	} while (menu_status == GFX_MONO_MENU_EVENT_IDLE);

	/* Handle the user's selection */
	switch (menu_status) {
	case 0:
		/* Change cpu frequency by modifying the prescalers */
		sysclk_set_prescalers(CLK_PSADIV_4_gc, CLK_PSBCDIV_1_1_gc);
		break;

	case 1:
		/* Change timing of the periodic temperature tests */
		OVEN_PERIODIC_TEMPTEST_TC.CTRLA = TC_CLKSEL_DIV256_gc;
		break;

	case 2:
		/* Change flash section. */
		oven_classb_flash_corrupter();
		break;

	case 3:
		/* Disrupt SRAM by setting up the DMA to write to a location on
		 * the heap, triggered by the class B frequency monitor timer
		 */
		PR.PRGEN &= ~PR_DMA_bm;
		DMA.CTRL |= DMA_ENABLE_bm;
		DMA.CH0.TRIGSRC = DMA_CH_TRIGSRC_TCD1_CCA_gc;
		/* Address of Timer D1 CNT base is 0x0960. */
		DMA.CH0.SRCADDR0 = 0x60;
		DMA.CH0.SRCADDR1 = 0x09;
		DMA.CH0.SRCADDR2 = 0x00;

		DMA.CH0.DESTADDR0 = ((uint16_t)&variable_for_sram_error) & 0xFF;
		DMA.CH0.DESTADDR1 = (((uint16_t)&variable_for_sram_error) >> 8)
				& 0xFF;
		DMA.CH0.DESTADDR2 = 0x00;

		DMA.CH0.CTRLA = DMA_CH_BURSTLEN_2BYTE_gc | DMA_CH_REPEAT_bm
				| DMA_CH_ENABLE_bm;
		break;

	case 4:
		/* Enter infinite loop */
		while (1) {
		}
		break;

	case 5:
		/* Set up ADC channel interrupt */
		adc_set_callback(&ADCA, adc_foul_callback);
		adcch_read_configuration(&ADCA, ADC_CH0, &adcch_conf);
		adcch_enable_interrupt(&adcch_conf);
		adcch_write_configuration(&ADCA, ADC_CH0, &adcch_conf);

		adcch_read_configuration(&ADCA, ADC_CH2, &adcch_conf);
		adcch_enable_interrupt(&adcch_conf);
		adcch_write_configuration(&ADCA, ADC_CH2, &adcch_conf);
		break;

	case 6:
		/* Back */
		break;

	case GFX_MONO_MENU_EVENT_EXIT:
		/* Fall through to default */
	default:
		/* Nothing, go back. */
		break;
	}
}