/** * \file * * \brief Main functions for Keyboard example * * Copyright (c) 2009-2018 Microchip Technology Inc. and its subsidiaries. * * \asf_license_start * * \page License * * Subject to your compliance with these terms, you may use Microchip * software and any derivatives exclusively with Microchip products. * It is your responsibility to comply with third party license terms applicable * to your use of third party software (including open source software) that * may accompany Microchip software. * * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, * WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, * INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE * LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL * LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE * SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE * POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT * ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY * RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY, * THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE. * * \asf_license_stop * */ /* * Support and FAQ: visit Microchip Support */ #include #include #include "main.h" #include "conf_usb.h" #include "udi_hid_kbd.h" #include "ui.h" #include #include #include "pwm.h" #include #include "keys.h" #include "serialconsole.h" #include "games.h" static volatile bool main_b_kbd_enable = false; enum status_code eepromstatus; /** * RTC Interrupt timing definition */ #define TIME_PERIOD_1MSEC 33u #define TIME_PERIOD_500MSEC 16500u /** * Variables */ uint32_t serialnum[4]; bool USBPower = false; uint8_t rotor_state; uint8_t rotor_position; volatile uint8_t PWM_Count; volatile uint32_t touch_time_counter = 0u; struct rtc_module rtc_instance; volatile uint32_t millis = 0; volatile uint32_t buzzer_counter = 0; volatile uint32_t buzzer_overflow = 250; volatile bool buzzer_state = false; volatile bool buzzer_skip = false; bool main_b_cdc_enable = false; uint8_t led1color[3]; uint8_t led2color[3]; uint8_t led3color[3]; uint8_t led4color[3]; uint8_t led1pressedcolor[3]; uint8_t led2pressedcolor[3]; uint8_t led3pressedcolor[3]; uint8_t led4pressedcolor[3]; volatile bool wait_for_sof = false; volatile bool button1 = false; volatile bool button2 = false; volatile bool button3 = false; volatile bool button4 = false; #define DEBOUNCE_TIME 200 volatile uint32_t lastButton1Press = 0; volatile uint32_t lastButton2Press = 0; volatile uint32_t lastButton3Press = 0; volatile uint32_t lastButton4Press = 0; uint8_t keymap[231]; uint8_t keymaplength; uint8_t keymapstarts[6]; uint8_t fwversion[1]; serial serialnumlist; //Challenge challengedata; ChallengeStruct challengedata; //Game gamedata; GameStruct gamedata; GameModes gamemode; extern struct tcc_module tcc2_instance; volatile bool games_buzzer_off = true; volatile uint32_t last_usb_comms = 0; /* Macros */ /** * \def GET_SENSOR_STATE(SENSOR_NUMBER) * \brief To get the sensor state that it is in detect or not * \param SENSOR_NUMBER for which the state to be detected * \return Returns either 0 or 1 * If the bit value is 0, it is not in detect * If the bit value is 1, it is in detect * Alternatively, the individual sensor state can be directly accessed using * p_qm_measure_data->p_sensor_states[(SENSOR_NUMBER/8)] variable. */ #define GET_SELFCAP_SENSOR_STATE(SENSOR_NUMBER) p_selfcap_measure_data-> \ p_sensor_states[(SENSOR_NUMBER / \ 8)] & (1 << (SENSOR_NUMBER % 8)) /** * \def GET_ROTOR_SLIDER_POSITION(ROTOR_SLIDER_NUMBER) * \brief To get the rotor angle or slider position. * These values are valid only when the sensor state for * corresponding rotor or slider shows in detect. * \param ROTOR_SLIDER_NUMBER for which the position to be known * \return Returns rotor angle or sensor position */ #define GET_SELFCAP_ROTOR_SLIDER_POSITION(ROTOR_SLIDER_NUMBER) \ p_selfcap_measure_data->p_rotor_slider_values[ \ ROTOR_SLIDER_NUMBER] /* Interrupt on "pin change" from push button to do wakeup on USB * Note: * This interrupt is enable when the USB host enable remote wakeup feature * This interrupt wakeup the CPU if this one is in idle mode */ /*static void ui_wakeup_handler(void) { // It is a wakeup then send wakeup USB udc_remotewakeup(); //LED_On(PIN_PA19); }*/ void vbus_handler(void){ if(port_pin_get_input_level(USB_VBUS_PIN)){ // Start USB stack to authorize VBus monitoring disable_usart_top(); udc_start(); USBPower = true; //configure_usart_top_default(); } else { //disable_usart_top(); udc_stop(); configure_usart_top_usb(); USBPower = false; } } /*! \brief Main function. Execution starts here. */ int main(void) { //Get chip serial number. We only use the last 4 bytes to save EEPROM space and to make comms faster serialnum[0] = *(volatile uint32_t *)0x0080A040; serialnum[1] = *(volatile uint32_t *)0x0080A044; serialnum[2] = *(volatile uint32_t *)0x0080A048; serialnum[3] = *(volatile uint32_t *)0x0080A00C; eepromstatus = rww_eeprom_emulator_init(); if(eepromstatus == STATUS_ERR_BAD_FORMAT){ rww_eeprom_emulator_erase_memory(); rww_eeprom_emulator_init(); } rww_eeprom_emulator_read_buffer(EEP_FIRMWARE_VERSION, fwversion, 1); if(fwversion[0] != FIRMWARE_VERSION){ //Clear eeprom and re-init with good values reset_eeprom(); } read_eeprom(); //uint8_t button1_state; //uint8_t button2_state; uint8_t slider_state; uint8_t slider_position; uint8_t last_slider_position; irq_initialize_vectors(); cpu_irq_enable(); // Initialize the sleep manager //sleepmgr_init(); #if !SAM0 sysclk_init(); board_init(); #else system_init(); #endif //Enable GCLK Generator 3 SYSCTRL->VREG.bit.RUNSTDBY = 1; // Configure GCLK3's divider - in this case, no division - so just divide by one / GCLK->GENDIV.reg = GCLK_GENDIV_ID(3) | GCLK_GENDIV_DIV(1); // Setup GCLK3 using the internal 8 MHz oscillator / GCLK->GENCTRL.reg = GCLK_GENCTRL_ID(3) | GCLK_GENCTRL_SRC_OSC8M | // Improve the duty cycle. / GCLK_GENCTRL_IDC | GCLK_GENCTRL_GENEN | GCLK_GENCTRL_RUNSTDBY; // Wait for the write to complete / while(GCLK->STATUS.bit.SYNCBUSY) {}; // Connect GCLK3 to SERCOM0 / GCLK->CLKCTRL.reg = GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK3 | GCLK_CLKCTRL_ID_SERCOM0_CORE; // Wait for the write to complete. / while (GCLK->STATUS.bit.SYNCBUSY) {}; delay_init(); sleepmgr_init(); struct port_config pin_conf; port_get_config_defaults(&pin_conf); /* Set buttons as inputs */ pin_conf.direction = PORT_PIN_DIR_INPUT; pin_conf.input_pull = PORT_PIN_PULL_UP; port_pin_set_config(BUTTON1, &pin_conf); port_pin_set_config(BUTTON2, &pin_conf); port_pin_set_config(BUTTON3, &pin_conf); port_pin_set_config(BUTTON4, &pin_conf); port_pin_set_config(MATRIX, &pin_conf); port_pin_set_config(MAX, &pin_conf); port_pin_set_config(ALIENS, &pin_conf); pin_conf.input_pull = PORT_PIN_PULL_DOWN; port_pin_set_config(USB_VBUS_PIN, &pin_conf); //Setup Pin Interrupts struct extint_chan_conf config_extint_chan; extint_chan_get_config_defaults(&config_extint_chan); //VBUS pin interrupt config_extint_chan.gpio_pin = PIN_PA01A_EIC_EXTINT1; config_extint_chan.gpio_pin_mux = PINMUX_PA01A_EIC_EXTINT1; config_extint_chan.gpio_pin_pull = EXTINT_PULL_DOWN; config_extint_chan.filter_input_signal = true; config_extint_chan.detection_criteria = EXTINT_DETECT_BOTH; extint_chan_set_config(1, &config_extint_chan); extint_register_callback(vbus_handler, 1, EXTINT_CALLBACK_TYPE_DETECT); extint_chan_enable_callback(1,EXTINT_CALLBACK_TYPE_DETECT); //Button 1 interrupt config_extint_chan.gpio_pin = PIN_PA04A_EIC_EXTINT4; config_extint_chan.gpio_pin_mux = PINMUX_PA04A_EIC_EXTINT4; config_extint_chan.gpio_pin_pull = EXTINT_PULL_UP; config_extint_chan.filter_input_signal = true; config_extint_chan.detection_criteria = EXTINT_DETECT_FALLING; extint_chan_set_config(4, &config_extint_chan); extint_register_callback(button1_handler, 4, EXTINT_CALLBACK_TYPE_DETECT); extint_chan_enable_callback(4,EXTINT_CALLBACK_TYPE_DETECT); //Button 2 interrupt config_extint_chan.gpio_pin = PIN_PA05A_EIC_EXTINT5; config_extint_chan.gpio_pin_mux = PINMUX_PA05A_EIC_EXTINT5; config_extint_chan.gpio_pin_pull = EXTINT_PULL_UP; config_extint_chan.filter_input_signal = true; config_extint_chan.detection_criteria = EXTINT_DETECT_FALLING; extint_chan_set_config(5, &config_extint_chan); extint_register_callback(button2_handler, 5, EXTINT_CALLBACK_TYPE_DETECT); extint_chan_enable_callback(5,EXTINT_CALLBACK_TYPE_DETECT); //Button 3 interrupt config_extint_chan.gpio_pin = PIN_PA06A_EIC_EXTINT6; config_extint_chan.gpio_pin_mux = PINMUX_PA06A_EIC_EXTINT6; config_extint_chan.gpio_pin_pull = EXTINT_PULL_UP; config_extint_chan.filter_input_signal = true; config_extint_chan.detection_criteria = EXTINT_DETECT_FALLING; extint_chan_set_config(6, &config_extint_chan); extint_register_callback(button3_handler, 6, EXTINT_CALLBACK_TYPE_DETECT); extint_chan_enable_callback(6,EXTINT_CALLBACK_TYPE_DETECT); //Button 4 interrupt config_extint_chan.gpio_pin = PIN_PA07A_EIC_EXTINT7; config_extint_chan.gpio_pin_mux = PINMUX_PA07A_EIC_EXTINT7; config_extint_chan.gpio_pin_pull = EXTINT_PULL_UP; config_extint_chan.filter_input_signal = true; config_extint_chan.detection_criteria = EXTINT_DETECT_FALLING; extint_chan_set_config(7, &config_extint_chan); extint_register_callback(button4_handler, 7, EXTINT_CALLBACK_TYPE_DETECT); extint_chan_enable_callback(7,EXTINT_CALLBACK_TYPE_DETECT); timer_init(); configure_usart(); configure_usart_callbacks(); if(port_pin_get_input_level(USB_VBUS_PIN)){ // Start USB stack to authorize VBus monitoring //disable_usart_top(); udc_start(); USBPower = true; //configure_usart_top_default(); } else { //disable_usart_top(); //udc_stop(); configure_usart_top_usb(); USBPower = false; } GCLK->GENCTRL.bit.RUNSTDBY = 1; //GCLK run standby touch_sensors_init(); pwm_init(); //Startup LED Sequence uint8_t delaytime = 40; led_on(LED1R); delay_cycles_ms(delaytime); led_on(LED2R); delay_cycles_ms(delaytime); led_on(LED3R); delay_cycles_ms(delaytime); led_on(LED4R); delay_cycles_ms(delaytime); led_off(LED1R); led_on(LED1G); delay_cycles_ms(delaytime); led_off(LED2R); led_on(LED2G); delay_cycles_ms(delaytime); led_off(LED3R); led_on(LED3G); delay_cycles_ms(delaytime); led_off(LED4R); led_on(LED4G); delay_cycles_ms(delaytime); led_off(LED1G); led_on(LED1B); delay_cycles_ms(delaytime); led_off(LED2G); led_on(LED2B); delay_cycles_ms(delaytime); led_off(LED3G); led_on(LED3B); delay_cycles_ms(delaytime); led_off(LED4G); led_on(LED4B); delay_cycles_ms(delaytime); led_off(LED1B); delay_cycles_ms(delaytime); led_off(LED2B); delay_cycles_ms(delaytime); led_off(LED3B); delay_cycles_ms(delaytime); led_off(LED4B); if(!port_pin_get_input_level(BUTTON1)){ gamemode = SIMON_SOLO; led_set_color(1,LED_COLOR_OFF); led_set_color(2,LED_COLOR_OFF); led_set_color(3,LED_COLOR_OFF); led_set_color(4,LED_COLOR_OFF); while(port_pin_get_input_level(BUTTON1) == false); button1 = false; } uart_event = millis; led_set_color(1,led1color); led_set_color(2,led2color); led_set_color(3,led3color); led_set_color(4,led4color); while(1){ //Check Buttons if(gamemode == IDLE){ //Game modes check the buttons themselves if(USBPower && ((millis - last_usb_comms) < 100)){ //Only send keys when connected to a computer if(button1){ button1 = false; //if(main_b_kbd_enable) send_keys(1); send_keys(1); } if(button2){ button2 = false; //if(main_b_kbd_enable) send_keys(2); send_keys(2); } if(button3){ button3 = false; //if(main_b_kbd_enable) send_keys(3); send_keys(3); } if(button4){ button4 = false; //if(main_b_kbd_enable) send_keys(4); send_keys(4); } //Check Touch Sensors touch_sensors_measure(); if (p_selfcap_measure_data->measurement_done_touch == 1u) { p_selfcap_measure_data->measurement_done_touch = 0u; slider_state = GET_SELFCAP_SENSOR_STATE(0); if(slider_state) { slider_position = GET_SELFCAP_ROTOR_SLIDER_POSITION(0); if(slider_position > last_slider_position + 10){ last_slider_position = slider_position; send_keys(6);//sliding down } if(slider_position < last_slider_position - 10){ last_slider_position = slider_position; send_keys(5);//sliding up } } } } } //Update USB serial console if we got data if(main_b_cdc_enable){ if(udi_cdc_get_nb_received_data()){ updateSerialConsole(); } } //Go to sleep to save battery //if (!USBPower && ((uart_event + 1000) < millis)) { if (!USBPower && ((millis - uart_event) > 1000) && gamemode != SIMON_SOLO) { standby_sleep(); } //Check serial ports check_comms(); run_games(); play_sounds(); } } void send_data(void){ const uint16_t data = 1; uint8_t delay = 50; usart_write_job(&usart_top_instance, &data); delay_cycles_ms(delay); usart_write_job(&usart_right_instance, &data); delay_cycles_ms(delay); usart_write_job(&usart_bottom_instance, &data); delay_cycles_ms(delay); usart_write_job(&usart_left_instance, &data); delay_cycles_ms(delay); usart_write_job(&usart_usba_instance, &data); delay_cycles_ms(delay); usart_write_job(&usart_usbc_instance, &data); delay_cycles_ms(delay); } void main_suspend_action(void) { //ui_powerdown(); } void main_resume_action(void) { //ui_wakeup(); } //void main_sof_action(void) void user_callback_sof_action(void) { wait_for_sof = false; last_usb_comms = millis; } void main_remotewakeup_enable(void) { //ui_wakeup_enable(); } void main_remotewakeup_disable(void) { //ui_wakeup_disable(); } //bool main_kbd_enable(void) void user_callback_vbus_action(bool b_vbus_high) { main_b_kbd_enable = b_vbus_high; if(main_b_kbd_enable){ disable_usart_top(); configure_usart_top_default(); } else { disable_usart_top(); configure_usart_top_usb(); } } void main_kbd_disable(void) { main_b_kbd_enable = false; } /*! \brief Configure the RTC timer overflow callback * */ void rtc_overflow_callback(void) { millis ++; /* Do something on RTC overflow here */ if(touch_time_counter == touch_time.measurement_period_ms) { touch_time.time_to_measure_touch = 1; touch_time.current_time_ms = touch_time.current_time_ms + touch_time.measurement_period_ms; touch_time_counter = 0u; } else { touch_time_counter++; } if(gamemode == SIMON_SOLO || gamemode == SIMON_MULTI_PRIMARY || gamemode == SIMON_MULTI_SECONDARY){ if(!port_pin_get_input_level(BUTTON1)){ tcc_restart_counter(&tcc2_instance); tcc_set_compare_value(&tcc2_instance,0,219); //415Hz led_set_color(1,LED_COLOR_GREEN); } if(!port_pin_get_input_level(BUTTON2)){ tcc_restart_counter(&tcc2_instance); tcc_set_compare_value(&tcc2_instance,0,293); //310Hz led_set_color(2,LED_COLOR_RED); } if(!port_pin_get_input_level(BUTTON3)){ tcc_restart_counter(&tcc2_instance); tcc_set_compare_value(&tcc2_instance,0,360); //252Hz led_set_color(3,LED_COLOR_YELLOW); } if(!port_pin_get_input_level(BUTTON4)){ tcc_restart_counter(&tcc2_instance); tcc_set_compare_value(&tcc2_instance,0,435); //209Hz led_set_color(4,LED_COLOR_BLUE); } if(port_pin_get_input_level(BUTTON1) & port_pin_get_input_level(BUTTON2) & port_pin_get_input_level(BUTTON3) & port_pin_get_input_level(BUTTON4) & games_buzzer_off){ //tcc_set_compare_value(&tcc2_instance,0,0); //off tcc_stop_counter(&tcc2_instance); led_set_color(1,LED_COLOR_OFF); led_set_color(2,LED_COLOR_OFF); led_set_color(3,LED_COLOR_OFF); led_set_color(4,LED_COLOR_OFF); } } } /*! \brief Configure the RTC timer callback * */ void configure_rtc_callbacks(void) { /* register callback */ rtc_count_register_callback(&rtc_instance, rtc_overflow_callback, RTC_COUNT_CALLBACK_OVERFLOW); /* Enable callback */ rtc_count_enable_callback(&rtc_instance,RTC_COUNT_CALLBACK_OVERFLOW); } /*! \brief Configure the RTC timer count after which interrupts comes * */ void configure_rtc_count(void) { struct rtc_count_config config_rtc_count; rtc_count_get_config_defaults(&config_rtc_count); config_rtc_count.prescaler = RTC_COUNT_PRESCALER_DIV_1; config_rtc_count.mode = RTC_COUNT_MODE_16BIT; config_rtc_count.continuously_update = true; /* initialize rtc */ rtc_count_init(&rtc_instance,RTC,&config_rtc_count); /* enable rtc */ rtc_count_enable(&rtc_instance); } /*! \brief Initialize timer * */ void timer_init(void) { /* Configure and enable RTC */ configure_rtc_count(); /* Configure and enable callback */ configure_rtc_callbacks(); /* Set Timer Period */ rtc_count_set_period(&rtc_instance,TIME_PERIOD_1MSEC); } void button1_handler(void){ if(button1 == false){ if((millis - lastButton1Press) > DEBOUNCE_TIME){ lastButton1Press = millis; button1 = true; uart_event = millis; } } } void button2_handler(void){ if(button2 == false){ if((millis - lastButton2Press) > DEBOUNCE_TIME){ lastButton2Press = millis; button2 = true; } } } void button3_handler(void){ if(button3 == false){ if((millis - lastButton3Press) > DEBOUNCE_TIME){ lastButton3Press = millis; button3 = true; } } } void button4_handler(void){ if(button4 == false){ if((millis - lastButton4Press) > DEBOUNCE_TIME){ lastButton4Press = millis; button4 = true; } } } bool main_cdc_enable(uint8_t port) { main_b_cdc_enable = true; // Open communication //uart_open(port); return true; } void main_cdc_disable(uint8_t port) { main_b_cdc_enable = false; // Close communication //uart_close(port); } void main_cdc_set_dtr(uint8_t port, bool b_enable) { if (b_enable) { // Host terminal has open COM //ui_com_open(port); }else{ // Host terminal has close COM //ui_com_close(port); } } void reset_eeprom(void){ //reset entire EEPROM including challenge and game data rww_eeprom_emulator_erase_memory(); rww_eeprom_emulator_init(); fwversion[0] = FIRMWARE_VERSION; rww_eeprom_emulator_write_buffer(EEP_FIRMWARE_VERSION, fwversion, 1); uint8_t eepdata[1]; eepdata[0] = 0; for(int x=1; x 0 //Reset badge challenge info in debug mode uint8_t bytes[80] = {0}; rww_eeprom_emulator_write_buffer(EEP_CHALLENGE_CONNECTED_TYPES, bytes, 5); rww_eeprom_emulator_write_buffer(EEP_CHALLENGE_BADGE_SERIALS, bytes, 80); rww_eeprom_emulator_write_buffer(EEP_GAME_SIMON_SOLO_HIGH_SCORE, bytes, 18); #endif uint8_t leddata[3]; leddata[0] = 255; //full brightness as default rww_eeprom_emulator_write_buffer(EEP_LED_BRIGHTNESS, leddata, 1); leddata[0] = 255; leddata[1] = 0; leddata[2] = 0; rww_eeprom_emulator_write_buffer(EEP_LED_1_COLOR, leddata, 3); leddata[0] = 0; leddata[1] = 255; leddata[2] = 0; rww_eeprom_emulator_write_buffer(EEP_LED_2_COLOR, leddata, 3); leddata[0] = 0; leddata[1] = 0; leddata[2] = 255; rww_eeprom_emulator_write_buffer(EEP_LED_3_COLOR, leddata, 3); leddata[0] = 127; leddata[1] = 127; leddata[2] = 127; rww_eeprom_emulator_write_buffer(EEP_LED_4_COLOR, leddata, 3); leddata[0] = 0; leddata[1] = 127; leddata[2] = 127; rww_eeprom_emulator_write_buffer(EEP_LED_1_PRESSED_COLOR, leddata, 3); leddata[0] = 127; leddata[1] = 0; leddata[2] = 127; rww_eeprom_emulator_write_buffer(EEP_LED_2_PRESSED_COLOR, leddata, 3); leddata[0] = 127; leddata[1] = 127; leddata[2] = 0; rww_eeprom_emulator_write_buffer(EEP_LED_3_PRESSED_COLOR, leddata, 3); leddata[0] = 0; leddata[1] = 0; leddata[2] = 0; rww_eeprom_emulator_write_buffer(EEP_LED_4_PRESSED_COLOR, leddata, 3); rww_eeprom_emulator_write_buffer(EEP_KEY_MAP, default_keymap, sizeof(default_keymap)); rww_eeprom_emulator_commit_page_buffer(); rww_eeprom_emulator_read_buffer(EEP_LED_1_COLOR, led1color, 3); led_set_color(1,led1color); rww_eeprom_emulator_read_buffer(EEP_LED_2_COLOR, led2color, 3); led_set_color(2,led2color); rww_eeprom_emulator_read_buffer(EEP_LED_3_COLOR, led3color, 3); led_set_color(3,led3color); rww_eeprom_emulator_read_buffer(EEP_LED_4_COLOR, led4color, 3); led_set_color(4,led4color); } void read_eeprom(void){ uint8_t bytes[18]; rww_eeprom_emulator_read_buffer(EEP_CHALLENGE_CONNECTED_TYPES,bytes, 5); challengedata.badgetypes = bytes[0]; challengedata.numconnected = bytes[1] | (bytes[2] << 8); challengedata.numshared = bytes[3] | (bytes[4] << 8); rww_eeprom_emulator_read_buffer(EEP_CHALLENGE_BADGE_SERIALS,serialnumlist.bytes, 80); rww_eeprom_emulator_read_buffer(EEP_GAME_SIMON_SOLO_HIGH_SCORE,bytes, 18); gamedata.simon_solo_high_score = bytes[0] | (bytes[1]<<8); gamedata.simon_multi_high_score = bytes[2] | (bytes[3]<<8); gamedata.simon_multi_connections = bytes[4] | (bytes[5]<<8); gamedata.simon_multi_games_played = bytes[6] | (bytes[7]<<8); gamedata.wam_solo_high_score = bytes[8] | (bytes[9]<<8); gamedata.wam_multi_high_score = bytes[10] | (bytes[11]<<8); gamedata.wam_multi_connections = bytes[12] | (bytes[13]<<8); gamedata.wam_multi_games_played = bytes[14] | (bytes[15]<<8); gamedata.wam_multi_wins = bytes[16] | (bytes[17]<<8); rww_eeprom_emulator_read_buffer(EEP_LED_1_COLOR, led1color, 3); rww_eeprom_emulator_read_buffer(EEP_LED_2_COLOR, led2color, 3); rww_eeprom_emulator_read_buffer(EEP_LED_3_COLOR, led3color, 3); rww_eeprom_emulator_read_buffer(EEP_LED_4_COLOR, led4color, 3); rww_eeprom_emulator_read_buffer(EEP_LED_1_PRESSED_COLOR, led1pressedcolor, 3); rww_eeprom_emulator_read_buffer(EEP_LED_2_PRESSED_COLOR, led2pressedcolor, 3); rww_eeprom_emulator_read_buffer(EEP_LED_3_PRESSED_COLOR, led3pressedcolor, 3); rww_eeprom_emulator_read_buffer(EEP_LED_4_PRESSED_COLOR, led4pressedcolor, 3); get_keymap(); } RAMFUNC void standby_sleep(void) { led_set_color(1,LED_COLOR_OFF); led_set_color(2,LED_COLOR_OFF); led_set_color(3,LED_COLOR_OFF); led_set_color(4,LED_COLOR_OFF); while(usart_get_job_status(&usart_top_instance, USART_TRANSCEIVER_TX) == STATUS_BUSY); while(usart_get_job_status(&usart_right_instance, USART_TRANSCEIVER_TX) == STATUS_BUSY); while(usart_get_job_status(&usart_bottom_instance, USART_TRANSCEIVER_TX) == STATUS_BUSY); while(usart_get_job_status(&usart_left_instance, USART_TRANSCEIVER_TX) == STATUS_BUSY); while(usart_get_job_status(&usart_usba_instance, USART_TRANSCEIVER_TX) == STATUS_BUSY); while(usart_get_job_status(&usart_usbc_instance, USART_TRANSCEIVER_TX) == STATUS_BUSY); tcc_stop_counter(&tcc2_instance); //Disable buzzer //Slow down RTC interrupts rtc_count_set_period(&rtc_instance,TIME_PERIOD_500MSEC); sleepmgr_sleep(SLEEPMGR_STANDBY); rtc_count_set_period(&rtc_instance,TIME_PERIOD_1MSEC); rtc_count_set_count(&rtc_instance,0); millis += 500; //Account for time while sleeping send_heartbeats(); } void usba_pin_interrupt_handler(void){ uart_event = millis; } /** * \mainpage ASF USB Device HID Keyboard * * \section intro Introduction * This example shows how to implement a USB Device HID Keyboard * on Atmel MCU with USB module. * The application note AVR4904 http://ww1.microchip.com/downloads/en/appnotes/doc8446.pdf * provides information about this implementation. * * \section startup Startup * The example uses the buttons or sensors available on the board * to simulate a standard keyboard. * After loading firmware, connect the board (EVKxx,Xplain,...) to the USB Host. * When connected to a USB host system this application provides a keyboard application * in the Unix/Mac/Windows operating systems. * This example uses the native HID driver for these operating systems. * * \copydoc UI * * \section example About example * * The example uses the following module groups: * - Basic modules: * Startup, board, clock, interrupt, power management * - USB Device stack and HID modules: *
services/usb/ *
services/usb/udc/ *
services/usb/class/hid/ *
services/usb/class/hid/keyboard/ * - Specific implementation: * - main.c, *
initializes clock *
initializes interrupt *
manages UI * - specific implementation for each target "./examples/product_board/": * - conf_foo.h configuration of each module * - ui.c implement of user's interface (buttons, leds) */