00001 /*This file is prepared for Doxygen automatic documentation generation.*/ 00020 00021 /* Copyright (c) 2009 Atmel Corporation. All rights reserved. 00022 * 00023 * Redistribution and use in source and binary forms, with or without 00024 * modification, are permitted provided that the following conditions are met: 00025 * 00026 * 1. Redistributions of source code must retain the above copyright notice, 00027 * this list of conditions and the following disclaimer. 00028 * 00029 * 2. Redistributions in binary form must reproduce the above copyright notice, 00030 * this list of conditions and the following disclaimer in the documentation 00031 * and/or other materials provided with the distribution. 00032 * 00033 * 3. The name of Atmel may not be used to endorse or promote products derived 00034 * from this software without specific prior written permission. 00035 * 00036 * 4. This software may only be redistributed and used in connection with an Atmel 00037 * AVR product. 00038 * 00039 * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED 00040 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 00041 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE EXPRESSLY AND 00042 * SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, 00043 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 00044 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 00045 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 00046 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00047 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 00048 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00049 */ 00050 00051 //_____ I N C L U D E S ___________________________________________________ 00052 00053 #include "config.h" 00054 #include "conf_usb.h" 00055 #include "usb_task.h" 00056 #include "lib_mcu/usb/usb_drv.h" 00057 #include "usb_descriptors.h" 00058 #include "lib_mcu/power/power_drv.h" 00059 #include "lib_mcu/wdt/wdt_drv.h" 00060 #include "lib_mcu/pll/pll_drv.h" 00061 #include "modules/usb/device_chap9/usb_device_task.h" 00062 00063 #ifndef USE_USB_PADS_REGULATOR 00064 #error "USE_USB_PADS_REGULATOR" should be defined as ENABLE or DISABLE in conf_usb.h file 00065 #endif 00066 00067 //_____ M A C R O S ________________________________________________________ 00068 00069 00070 00071 //_____ D E F I N I T I O N S ______________________________________________ 00072 00083 volatile U16 g_usb_event=0; 00084 00085 00086 #if (USB_DEVICE_FEATURE == ENABLED) 00093 extern bit usb_connected; 00094 00101 extern U8 usb_configuration_nb; 00102 00107 extern U8 remote_wakeup_feature; 00108 00109 #ifdef WA_USB_SUSPEND_PERTUBATION 00110 volatile U16 delay_usb; 00111 void usb_delay_ms(U8 ms); 00112 #endif 00113 #endif 00114 00115 //_____ D E C L A R A T I O N S ____________________________________________ 00116 00126 void usb_task_init(void) 00127 { 00128 #if (USE_USB_PADS_REGULATOR==ENABLE) // Otherwise assume USB PADs regulator is not used 00129 Usb_enable_regulator(); 00130 #endif 00131 usb_device_task_init(); 00132 } 00133 00143 void usb_task(void) 00144 { 00145 usb_device_task(); 00146 } 00147 00166 #ifdef __GNUC__ 00167 ISR(USB_GEN_vect) 00168 #else 00169 #pragma vector = USB_General_vect 00170 __interrupt void usb_general_interrupt() 00171 #endif 00172 { 00173 // - Device start of frame received 00174 if (Is_usb_sof() && Is_sof_interrupt_enabled()) 00175 { 00176 Usb_ack_sof(); 00177 Usb_sof_action(); 00178 } 00179 // - Device Suspend event (no more USB activity detected) 00180 if (Is_usb_suspend() && Is_suspend_interrupt_enabled()) 00181 { 00182 usb_suspended=TRUE; 00183 Usb_ack_wake_up(); // clear wake up to detect next event 00184 Usb_send_event(EVT_USB_SUSPEND); 00185 Usb_ack_suspend(); 00186 Usb_enable_wake_up_interrupt(); 00187 Usb_disable_resume_interrupt(); 00188 Usb_freeze_clock(); 00189 Stop_pll(); 00190 Usb_suspend_action(); 00191 } 00192 // - Wake up event (USB activity detected): Used to resume 00193 if (Is_usb_wake_up() && Is_wake_up_interrupt_enabled()) 00194 { 00195 if(Is_pll_ready()==FALSE) 00196 { 00197 #ifdef USE_USB_AUTOBAUD 00198 usb_autobaud(); 00199 #else 00200 Pll_start_auto(); 00201 #endif 00202 Wait_pll_ready(); 00203 } 00204 Usb_unfreeze_clock(); 00205 Usb_ack_wake_up(); 00206 if(usb_suspended) 00207 { 00208 #ifdef WA_USB_SUSPEND_PERTUBATION 00209 Usb_enable_resume_interrupt(); 00210 Usb_enable_reset_interrupt(); 00211 while(Is_usb_wake_up()) 00212 { 00213 Usb_ack_wake_up(); 00214 } 00215 usb_delay_ms(2); 00216 if(Is_usb_sof() || Is_usb_resume() || Is_usb_reset() ) 00217 { 00218 Usb_disable_wake_up_interrupt(); 00219 Usb_wake_up_action(); 00220 Usb_send_event(EVT_USB_WAKE_UP); 00221 Usb_enable_suspend_interrupt(); 00222 Usb_enable_resume_interrupt(); 00223 Usb_enable_reset_interrupt(); 00224 00225 } 00226 else // Workarround to make the USB enter power down mode again (spurious transcient detected on the USB lines) 00227 { 00228 Usb_ack_wake_up(); // clear wake up to detect next event 00229 Usb_send_event(EVT_USB_SUSPEND); 00230 Usb_ack_suspend(); 00231 Usb_enable_wake_up_interrupt(); 00232 Usb_disable_resume_interrupt(); 00233 Usb_freeze_clock(); 00234 Stop_pll(); 00235 Usb_suspend_action(); 00236 } 00237 #else 00238 Usb_enable_resume_interrupt(); 00239 Usb_enable_reset_interrupt(); 00240 Usb_ack_wake_up(); 00241 Usb_disable_wake_up_interrupt(); 00242 Usb_wake_up_action(); 00243 Usb_send_event(EVT_USB_WAKE_UP); 00244 Usb_enable_suspend_interrupt(); 00245 Usb_enable_resume_interrupt(); 00246 Usb_enable_reset_interrupt(); 00247 #endif 00248 } 00249 } 00250 // - Resume state bus detection 00251 if (Is_usb_resume() && Is_resume_interrupt_enabled()) 00252 { 00253 usb_suspended = FALSE; 00254 Usb_disable_wake_up_interrupt(); 00255 Usb_ack_resume(); 00256 Usb_disable_resume_interrupt(); 00257 Usb_resume_action(); 00258 Usb_send_event(EVT_USB_RESUME); 00259 } 00260 // - USB bus reset detection 00261 if (Is_usb_reset()&& Is_reset_interrupt_enabled()) 00262 { 00263 Usb_ack_reset(); 00264 usb_init_device(); 00265 Usb_reset_action(); 00266 Usb_send_event(EVT_USB_RESET); 00267 } 00268 00269 } 00270 00271 00272 #ifdef WA_USB_SUSPEND_PERTUBATION 00273 void usb_delay_ms(U8 ms) 00274 { 00275 for(;ms;ms--) 00276 { 00277 for(delay_usb=0;delay_usb<FOSC/16;delay_usb++); 00278 } 00279 } 00280 #endif 00281