00001 /*This file has been prepared for Doxygen automatic documentation generation.*/ 00025 00026 /* Copyright (c) 2007, 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 * THIS SOFTWARE IS PROVIDED BY ATMEL ``AS IS'' AND ANY EXPRESS OR IMPLIED 00042 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 00043 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY AND 00044 * SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, 00045 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 00046 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 00047 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 00048 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00049 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 00050 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00051 */ 00052 00053 //_____ I N C L U D E S ___________________________________________________ 00054 00055 #include "config.h" 00056 #include "conf_usb.h" 00057 #include "usb_task.h" 00058 #include "lib_mcu/usb/usb_drv.h" 00059 #include "usb_descriptors.h" 00060 #include "lib_mcu/power/power_drv.h" 00061 #include "lib_mcu/wdt/wdt_drv.h" 00062 #include "lib_mcu/pll/pll_drv.h" 00063 #include "modules/usb/device_chap9/usb_device_task.h" 00064 00065 #ifndef USE_USB_PADS_REGULATOR 00066 #error "USE_USB_PADS_REGULATOR" should be defined as ENABLE or DISABLE in conf_usb.h file 00067 #endif 00068 00069 //_____ M A C R O S ________________________________________________________ 00070 00071 00072 00073 //_____ D E F I N I T I O N S ______________________________________________ 00074 00085 volatile U16 g_usb_event=0; 00086 00087 00088 #if (USB_DEVICE_FEATURE == ENABLED) 00095 extern bit usb_connected; 00096 00103 extern U8 usb_configuration_nb; 00104 00109 extern U8 remote_wakeup_feature; 00110 00111 volatile U16 delay_usb; 00112 void usb_delay_ms(U8 ms); 00113 #endif 00114 00115 00116 00117 //_____ D E C L A R A T I O N S ____________________________________________ 00118 00128 void usb_task_init(void) 00129 { 00130 #if (USE_USB_PADS_REGULATOR==ENABLE) // Otherwise assume USB PADs regulator is not used 00131 Usb_enable_regulator(); 00132 #endif 00133 usb_device_task_init(); 00134 } 00135 00145 void usb_task(void) 00146 { 00147 usb_device_task(); 00148 } 00149 00168 #ifdef __GNUC__ 00169 ISR(USB_GEN_vect) 00170 #else 00171 #pragma vector = USB_General_vect 00172 __interrupt void usb_general_interrupt() 00173 #endif 00174 { 00175 // - Device start of frame received 00176 if (Is_usb_sof() && Is_sof_interrupt_enabled()) 00177 { 00178 Usb_ack_sof(); 00179 Usb_sof_action(); 00180 } 00181 // - Device Suspend event (no more USB activity detected) 00182 if (Is_usb_suspend() && Is_suspend_interrupt_enabled()) 00183 { 00184 usb_suspended=TRUE; 00185 Usb_ack_wake_up(); // clear wake up to detect next event 00186 Usb_send_event(EVT_USB_SUSPEND); 00187 Usb_ack_suspend(); 00188 Usb_enable_wake_up_interrupt(); 00189 Usb_disable_resume_interrupt(); 00190 Usb_freeze_clock(); 00191 Stop_pll(); 00192 Usb_suspend_action(); 00193 } 00194 // - Wake up event (USB activity detected): Used to resume 00195 if (Is_usb_wake_up() && Is_wake_up_interrupt_enabled()) 00196 { 00197 if(Is_pll_ready()==FALSE) 00198 { 00199 #ifdef USE_USB_AUTOBAUD 00200 usb_autobaud(); 00201 #else 00202 Pll_start_auto(); 00203 #endif 00204 Wait_pll_ready(); 00205 } 00206 Usb_unfreeze_clock(); 00207 Usb_ack_wake_up(); 00208 if(usb_suspended) 00209 { 00210 Usb_enable_resume_interrupt(); 00211 Usb_enable_reset_interrupt(); 00212 while(Is_usb_wake_up()) 00213 { 00214 Usb_ack_wake_up(); 00215 } 00216 usb_delay_ms(2); 00217 if(Is_usb_sof() || Is_usb_resume() || Is_usb_reset() ) 00218 { 00219 Usb_disable_wake_up_interrupt(); 00220 Usb_wake_up_action(); 00221 Usb_send_event(EVT_USB_WAKE_UP); 00222 Usb_enable_suspend_interrupt(); 00223 Usb_enable_resume_interrupt(); 00224 Usb_enable_reset_interrupt(); 00225 00226 } 00227 else // Workarround to make the USB enter power down mode again (spurious transcient detected on the USB lines) 00228 { 00229 if(Is_usb_wake_up()) return; 00230 Usb_drive_dp_low(); 00231 Usb_direct_drive_usb_enable(); 00232 Usb_direct_drive_disable(); 00233 Usb_disable_wake_up_interrupt(); 00234 } 00235 } 00236 } 00237 // - Resume state bus detection 00238 if (Is_usb_resume() && Is_resume_interrupt_enabled()) 00239 { 00240 usb_suspended = FALSE; 00241 Usb_disable_wake_up_interrupt(); 00242 Usb_ack_resume(); 00243 Usb_disable_resume_interrupt(); 00244 Usb_resume_action(); 00245 Usb_send_event(EVT_USB_RESUME); 00246 } 00247 // - USB bus reset detection 00248 if (Is_usb_reset()&& Is_reset_interrupt_enabled()) 00249 { 00250 Usb_ack_reset(); 00251 usb_init_device(); 00252 Usb_reset_action(); 00253 Usb_send_event(EVT_USB_RESET); 00254 } 00255 00256 } 00257 00258 00259 void usb_delay_ms(U8 ms) 00260 { 00261 for(;ms;ms--) 00262 { 00263 for(delay_usb=0;delay_usb<FOSC/16;delay_usb++); 00264 } 00265 }