00001 /* ---------------------------------------------------------------------------- 00002 * SAM Software Package License 00003 * ---------------------------------------------------------------------------- 00004 * Copyright (c) 2015, Atmel Corporation 00005 * 00006 * All rights reserved. 00007 * 00008 * Redistribution and use in source and binary forms, with or without 00009 * modification, are permitted provided that the following conditions are met: 00010 * 00011 * - Redistributions of source code must retain the above copyright notice, 00012 * this list of conditions and the disclaimer below. 00013 * 00014 * Atmel's name may not be used to endorse or promote products derived from 00015 * this software without specific prior written permission. 00016 * 00017 * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR 00018 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 00019 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE 00020 * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT, 00021 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 00022 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 00023 * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 00024 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 00025 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 00026 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00027 * ---------------------------------------------------------------------------- 00028 */ 00029 /** 00030 * \defgroup UI User Interface 00031 * 00032 * Human interface on SAM V71 Xplained Ultra board: 00033 * - Led 0 is continuously on when a device is connected 00034 * - Led 0 blinks when the device is enumerated and USB in idle mode 00035 * - The blink is slow (1s) with low speed device 00036 * - The blink is normal (0.5s) with full speed device 00037 * - The blink is fast (0.25s) with high speed device 00038 * - Led 1 is on when a read or write access is on going 00039 * - Led 1 is on when a LUN test is success 00040 * - Led 1 blinks when a LUN test is unsuccess 00041 */ 00042 00043 #include "board.h" 00044 #include "ui.h" 00045 #include "ctrl_access.h" 00046 #include "uhi_msc_mem.h" 00047 00048 /* Wakeup pin is RIGHT CLICK (fast wakeup 14) */ 00049 #define RESUME_PMC_FSTT (PMC_FSMR_FSTT14) 00050 #define RESUME_PIN (GPIO_PUSH_BUTTON_2) 00051 #define RESUME_PIO (PIN_PUSHBUTTON_2_PIO) 00052 #define RESUME_PIO_ID (PIN_PUSHBUTTON_2_ID) 00053 #define RESUME_PIO_MASK (PIN_PUSHBUTTON_2_MASK) 00054 #define RESUME_PIO_ATTR (PIN_PUSHBUTTON_2_ATTR) 00055 00056 /** 00057 * \name Internal routines to manage asynchronous interrupt pin change 00058 * This interrupt is connected to a switch and allows to wakeup CPU in low sleep 00059 * mode. 00060 * This wakeup the USB devices connected via a downstream resume. 00061 * @{ 00062 */ 00063 static void ui_enable_asynchronous_interrupt(void); 00064 static void ui_disable_asynchronous_interrupt(void); 00065 00066 /* Interrupt on "pin change" from RIGHT CLICK to do wakeup on USB 00067 * Note: 00068 * This interrupt is enable when the USB host enable remotewakeup feature 00069 * This interrupt wakeup the CPU if this one is in idle mode */ 00070 static void ui_wakeup_handler(uint32_t id, uint32_t mask) 00071 { 00072 /*if (RESUME_PIO_ID == id && RESUME_PIO_MASK == mask) { 00073 if (USBH_is_suspend()) { 00074 ui_disable_asynchronous_interrupt(); 00075 00076 // Wakeup host and device 00077 USBH_resume(); 00078 } 00079 }*/ 00080 } 00081 00082 /** 00083 * \brief Initializes and enables interrupt pin change 00084 */ 00085 static void ui_enable_asynchronous_interrupt(void) 00086 { 00087 /* Enable interrupt for button pin */ 00088 /*pio_get_interrupt_status(PIOB); 00089 pio_enable_pin_interrupt(GPIO_PUSH_BUTTON_2); 00090 /* Enable fastwakeup for button pin */ 00091 //pmc_set_fast_startup_input(PMC_FSMR_FSTT14); 00092 } 00093 00094 /** 00095 * \brief Disables interrupt pin change 00096 */ 00097 static void ui_disable_asynchronous_interrupt(void) 00098 { 00099 /* Disable interrupt for button pin */ 00100 //pio_disable_pin_interrupt(GPIO_PUSH_BUTTON_2); 00101 //pio_get_interrupt_status(PIOB); 00102 /* Enable fastwakeup for button pin */ 00103 //pmc_clr_fast_startup_input(PMC_FSMR_FSTT14); 00104 } 00105 00106 /*! @} */ 00107 00108 /** 00109 * \name Main user interface functions 00110 * @{ 00111 */ 00112 void ui_init(void) 00113 { 00114 /* Enable PIO clock for button inputs */ 00115 //pmc_enable_periph_clk(ID_PIOB); 00116 //pmc_enable_periph_clk(ID_PIOE); 00117 /* Set handler for wakeup */ 00118 //pio_handler_set(RESUME_PIO, RESUME_PIO_ID, RESUME_PIO_MASK, 00119 // RESUME_PIO_ATTR, ui_wakeup_handler); 00120 /* Enable IRQ for button (PIOB) */ 00121 //NVIC_EnableIRQ((IRQn_Type)RESUME_PIO_ID); 00122 /* Enable interrupt for button pin */ 00123 //pio_get_interrupt_status(RESUME_PIO); 00124 //pio_configure_pin(RESUME_PIN, RESUME_PIO_ATTR); 00125 //pio_enable_pin_interrupt(RESUME_PIN); 00126 /* Enable fastwakeup for button pin */ 00127 //pmc_set_fast_startup_input(RESUME_PMC_FSTT); 00128 /* Initialize LEDs */ 00129 LED_Configure( LED_YELLOW0 ) ; 00130 LED_Configure( LED_YELLOW1 ) ; 00131 00132 LED_Clear(LED_YELLOW0); 00133 LED_Clear(LED_YELLOW1); 00134 00135 } 00136 00137 void ui_usb_mode_change(bool b_host_mode) 00138 { 00139 UNUSED(b_host_mode); 00140 ui_init(); 00141 } 00142 00143 /*! @} */ 00144 00145 /** 00146 * \name Host mode user interface functions 00147 * @{ 00148 */ 00149 00150 /*! Status of device enumeration */ 00151 static USBH_enum_status_t ui_enum_status = UHC_ENUM_DISCONNECT; 00152 /*! Blink frequency depending on device speed */ 00153 static uint16_t ui_device_speed_blink; 00154 /*! Status of the MSC test */ 00155 static bool ui_test_done; 00156 /*! Result of the MSC test */ 00157 static bool ui_test_result; 00158 00159 void ui_usb_vbus_change(bool b_vbus_present) 00160 { 00161 /*if (b_vbus_present) { 00162 //LED_Set(LED3_GPIO); 00163 } else { 00164 //LED_Clear(LED3_GPIO); 00165 }*/ 00166 } 00167 00168 void ui_usb_vbus_error(void) 00169 { 00170 } 00171 00172 void ui_usb_connection_event(USBH_device_t *dev, bool b_present) 00173 { 00174 UNUSED(dev); 00175 if (b_present) { 00176 LED_Set(LED_YELLOW0); 00177 } else { 00178 LED_Clear(LED_YELLOW0); 00179 ui_enum_status = UHC_ENUM_DISCONNECT; 00180 } 00181 } 00182 00183 void ui_usb_enum_event(USBH_device_t *dev, USBH_enum_status_t status) 00184 { 00185 UNUSED(dev); 00186 ui_enum_status = status; 00187 switch (dev->speed) { 00188 case UHD_SPEED_HIGH: 00189 ui_device_speed_blink = 250; 00190 break; 00191 00192 case UHD_SPEED_FULL: 00193 ui_device_speed_blink = 500; 00194 break; 00195 00196 case UHD_SPEED_LOW: 00197 default: 00198 ui_device_speed_blink = 1000; 00199 break; 00200 } 00201 ui_test_done = false; 00202 } 00203 00204 void ui_usb_wakeup_event(void) 00205 { 00206 ui_disable_asynchronous_interrupt(); 00207 } 00208 00209 void ui_usb_sof_event(void) 00210 { 00211 bool b_btn_state; 00212 static bool btn_suspend = false; 00213 static uint16_t counter_sof = 0; 00214 00215 if (ui_enum_status == UHC_ENUM_SUCCESS) { 00216 /* Display device enumerated and in active mode */ 00217 if (++counter_sof > ui_device_speed_blink) { 00218 counter_sof = 0; 00219 LED_Toggle(LED_YELLOW0); 00220 if (ui_test_done && !ui_test_result) { 00221 /* Test fail then blink led */ 00222 LED_Toggle(LED_YELLOW1); 00223 } 00224 } 00225 } 00226 } 00227 00228 void ui_test_flag_reset(void) 00229 { 00230 ui_test_done = false; 00231 LED_Clear(LED_YELLOW0); 00232 } 00233 00234 void ui_test_finish(bool b_success) 00235 { 00236 ui_test_done = true; 00237 ui_test_result = b_success; 00238 if (b_success) { 00239 LED_Set(LED_YELLOW1); 00240 } 00241 } 00242 00243 /*! @} */ 00244 00245 /*! \name Callback to show the MSC read and write access 00246 * @{ */ 00247 void ui_start_read(void) 00248 { 00249 LED_Set(LED_YELLOW1); 00250 } 00251 00252 void ui_stop_read(void) 00253 { 00254 LED_Clear(LED_YELLOW1); 00255 } 00256 00257 void ui_start_write(void) 00258 { 00259 LED_Set(LED_YELLOW1); 00260 } 00261 00262 void ui_stop_write(void) 00263 { 00264 LED_Clear(LED_YELLOW1); 00265 } 00266 00267 /*! @} */