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