otg_user_task.c

Go to the documentation of this file.
00001 // *************************************************************************************************************
00002 // * This is the user program file for the OTG HID demonstration package (AT90USB647/1287)
00003 // * In addition to the OTG firmware features, it includes :
00004 // *  - request specific OTG features from pushbuttons :
00005 // *    + HOST MODE :
00006 // *      - HWB : toggle Vbus (from any state of an A-Device)
00007 // *      - Joystick SELECT/CENTER : request HNP (from A-HOST or B-HOST)
00008 // *    + PERIPH MODE :
00009 // *      - HWB : send a SRP (from B-IDLE only)
00010 // *      - Joystick SELECT/CENTER : toggle Host' Hid LED  (from A-PERIPH or B-PERIPH only)
00011 // *
00012 // *  - handle a basic HID mouse application : 
00013 // *     -> in Device mode, the device sends a report indicating a click on CENTER pushbutton
00014 // *     -> in Host mode, a mouse or HID compatible device can be connected. The firmware toggle the LED state on each click
00015 // *
00016 // *  - LED for messaging feature : 4 monocolor LED on STK525, 2 bicolor LED on USBKEY
00017 //*     Refer to "otg_user_task." for LED assignment
00018 // *     -> Led_noresponse (Red) : "Device No Response" signalling
00019 // *     -> Led_usb_connected (Green) : role identifier, this LED is ON in PERIPHERAL mode, when enumerated
00020 // *     -> Led_hid (Green) : on HOST side, this LED is toggled each time the Peripheral sends a CLICK report
00021 // *     -> Led_unsupported (Red) : "Unsupported Device" signalling
00022 // *************************************************************************************************************
00023 
00024 // MCU is using an external 8 MHz quartz
00025 // User must indicate the clock prescaler configuration set up (in order to generate constants 2ms interruptions)
00026 #define   OSC_CORE_PRESCALER    NO_PRESC
00027  
00028 //___________I N C L U D E S___________________________
00029 #include "config.h"
00030 #include "conf_usb.h"
00031 #include "lib_mcu/usb/usb_drv.h"
00032 #include "modules/usb/usb_task.h"
00033 #include "modules/usb/device_chap9/usb_standard_request.h"
00034 #include "modules/usb/host_chap9/usb_host_task.h"
00035 #include "modules/usb/device_chap9/usb_device_task.h"
00036 #include "modules/usb/host_chap9/usb_host_enum.h"
00037 #include "lib_mcu/timer/timer16_drv.h"
00038 #include "lib_mcu/usb/usb_drv.h"
00039 #include "otg_user_task.h"
00040 //#include "lib_mcu/adc/adc_drv.h"
00041 #include "lib_mcu/pll/pll_drv.h" 
00042 
00043 
00044 //___________V A R I A B L E S__________________________
00045 U8 PIPE_SPIDER_IN;
00046 
00047 volatile U8 button_high;
00048 
00049 volatile U8 device_connected;
00050 volatile U8 previous_session, previous_vbus;
00051 
00052 volatile S8 mouse_move;
00053 volatile S8 Usb_report[4];
00054 volatile U8 Usb_report_status;
00055 
00056 #if (USE_TIMER16 == BOTH_TIMER16)
00057   U8  timer16_selected;
00058 #endif
00059 
00060 
00061 // ***************************************
00062 // **
00063 // **  MAIN PROGRAM
00064 // **
00065 // ***************************************
00066 
00067 void otg_user_task_init(void)
00068 {
00069   // Board init
00070   Leds_init();
00071   Joy_init();
00072   Hwb_button_init();
00073   Leds_off();
00074   
00075   previous_session = SESSION_DEVICE;  // to make the function Led_print_otg_status() display the first status
00076   previous_vbus = 0;
00077   device_connected = SESSION_OFF;
00078   Led_print_otg_status();
00079 
00080   Enable_interrupt();
00081   
00082   Clear_usb_report();
00083   Usb_report_status = USB_READ_PACKET;
00084   button_high = FALSE;
00085 }
00086 
00087 
00088 void otg_user_task(void)
00089 {
00090 U8 i;
00091 
00092   // ==============================
00093   // ** USB low-level management **
00094   // ==============================
00095 
00096   // ================
00097   // In HOST mode, USB high-level management
00098   // ================
00099   if (Is_usb_host_enabled())
00100   {
00101     if (Is_host_ready())
00102     {
00103     // In HOST mode, check if a new peripheral has been connected
00104       if (Is_new_device_connection_event())
00105       {
00106         for(i=0;i<Get_nb_supported_interface();i++)
00107         {
00108            if (Get_class(i)==HID_CLASS && Get_protocol(i)==MOUSE_PROTOCOL)
00109            {
00110               device_connected = SESSION_HOST;
00111               Led_usb_connected_off();
00112               Led_hid_off();
00113               host_hid_set_idle();
00114               host_get_hid_repport_descriptor();
00115               PIPE_SPIDER_IN = host_get_hwd_pipe_nb(Get_ep_addr(i,0));
00116               Host_select_pipe(PIPE_SPIDER_IN);
00117               Host_continuous_in_mode();
00118               Host_unfreeze_pipe();
00119               button_high = FALSE;
00120               mouse_move = 0;
00121               break;
00122            }
00123         }
00124       }
00125     }
00126     else
00127     {
00128       Led_usb_connected_off();
00129       Led_hid_off();
00130       device_connected = SESSION_OFF;
00131     }
00132       
00133 
00134     // Disconnection event
00135     if(Is_device_disconnection_event())
00136     {
00137       Led_usb_connected_off();
00138       Led_hid_off();
00139       device_connected = SESSION_OFF;
00140     }
00141 
00142     // In HOST mode, check for new packet received
00143     if (device_connected == SESSION_HOST)  // Peripheral is connected and enumerated
00144     {
00145       // 1. Get new data from Device
00146       Host_select_pipe(PIPE_SPIDER_IN);
00147       if ((Is_host_in_received()) && (Is_host_stall()==FALSE) && (Usb_report_status != USB_NEW_PACKET))
00148       {
00149         i = 0;
00150         while ((UPBCLX != 0) && (i != 4))
00151         {
00152           Usb_report[i] = Host_read_byte();
00153           i++;
00154         }
00155         Usb_report_status = USB_NEW_PACKET;
00156 
00157         Host_ack_in_received();
00158         Host_send_in();
00159       }
00160     }
00161   }
00162 
00163   // ================
00164   // In DEVICE mode, USB high-level management
00165   // ================
00166   if (Is_usb_device_enabled())
00167   {
00168     if (usb_configuration_nb != 0)  // is device configured and enumerated ?
00169     {
00170       Led_usb_connected_on();
00171       device_connected = SESSION_DEVICE;
00172       Usb_select_endpoint(EP_SPIDER_IN);    // endpoint sending data to HOST
00173       if ((Is_usb_write_enabled()) && (Usb_report_status == USB_NEW_PACKET))
00174       {
00175         Usb_write_byte(Usb_report[0]);
00176         Usb_write_byte(Usb_report[1]);
00177         Usb_write_byte(Usb_report[2]);
00178         Usb_write_byte(Usb_report[3]);
00179         Usb_report_status = USB_READ_PACKET;
00180         Usb_ack_fifocon();               // Send data over the USB
00181         Clear_usb_report();
00182       }
00183     }
00184     else
00185     {
00186       Led_usb_connected_off();
00187       Led_hid_off();
00188       device_connected = SESSION_OFF;
00189     }
00190   }
00191 
00192 
00193   // =======================
00194   // ** Application level **
00195   // DEVICE mode : send HID report with information about CENTER pushbutton (push / release)
00196   // HOST mode : toggle the LED according to button position
00197   // =======================
00198   if (device_connected == SESSION_DEVICE)
00199   {
00200     // Acquires moves from mouse
00201     // If notorious change (more than 4%), the difference is sent to Host
00202     if (Usb_report_status != USB_NEW_PACKET)
00203     {
00204       if (Is_joy_select())
00205       {
00206         // Pushbutton debounce is handled by USB Pipe polling frequency (EP_INTERVAL_1 value in "usb_descriptors.h")
00207         Usb_report[0] = 0x01;
00208         Usb_report_status = USB_NEW_PACKET;
00209       }
00210       else
00211       {
00212         Usb_report[0] = 0x00;
00213         Usb_report_status = USB_NEW_PACKET;
00214       }
00215     }
00216   }
00217 
00218   if (device_connected == SESSION_HOST)
00219   {
00220     if (Usb_report_status == USB_NEW_PACKET)
00221     {
00222       if ((Usb_report[0]&0x01) == 0)
00223       {
00224         if (button_high == TRUE)    { button_high = FALSE; }
00225       }
00226       else
00227       {
00228         if (button_high == FALSE)
00229         {
00230           button_high = TRUE;
00231           Led_hid_toggle();
00232         }        
00233       }
00234       Usb_report_status = USB_READ_PACKET;
00235       Clear_usb_report();
00236     }
00237   }
00238 
00239   
00240   
00241   // =================================================================
00242   // OTG User Request Management
00243   // According to the Role, pushbuttons will initiate different events
00244   // =================================================================
00245   if (Is_usb_device_enabled())
00246   {
00247     if (!Is_usb_id_host() && (usb_configuration_nb == 0))
00248     {
00249       // SRP Request : HWB Button
00250       // ***********
00251       if (Is_hwb())
00252       {
00253         Bp_delay_debounce();
00254         while (Is_hwb());
00255         Bp_delay_debounce();
00256         Set_user_request_srp();
00257       }
00258     }
00259     if (Is_usb_id_host())
00260     {
00261       // VBUS Toggle Request : HWB Button   // to allow session ends when in A-PERIPHERAL mode
00262       // *******************
00263       if (Is_hwb())
00264       {
00265         Bp_delay_debounce();
00266         while (Is_hwb());
00267         Bp_delay_debounce();
00268         Set_user_request_vbus();
00269       }
00270     }
00271   }
00272 
00273   if (Is_usb_host_enabled())
00274   {
00275     // VBUS Toggle Request : HWB Button
00276     // *******************
00277     if (Is_hwb())
00278     {
00279       Bp_delay_debounce();
00280       while (Is_hwb());
00281       Bp_delay_debounce();
00282       Set_user_request_vbus();
00283     }
00284     
00285     // HNP Toggle Request : CENTER Button
00286     // *******************
00287     if (Is_joy_select())
00288     {
00289       Bp_delay_debounce();
00290       while (Is_joy_select());
00291       Bp_delay_debounce();
00292       Set_user_request_hnp();
00293     }
00294   }
00295 
00296   Led_print_otg_status();
00297 }
00298 
00299 
00300 
00301 
00302 
00303 // This function actualizes the OTG status line when called
00304 // It displays the VBUS state and the current SESSION (HOST, DEVICE, OFF ; other states can be added - 4 letters)
00305 void Led_print_otg_status(void)
00306 {
00307   U8 vbus_state = 0;
00308   if ((Is_usb_vbus_high()) || ((Is_usb_id_host()) && ((PORTE&0x80) != 0)))    { vbus_state = 1; }
00309   if ((previous_session != device_connected) || (previous_vbus != vbus_state))
00310   {
00311     switch (device_connected)
00312     {
00313     case SESSION_HOST:
00314       Led_usb_connected_off();
00315       break;
00316 
00317     case SESSION_DEVICE:
00318       Led_usb_connected_on();
00319       break;
00320 
00321     case SESSION_OFF:
00322       Led_usb_connected_off();
00323       break;
00324 
00325     default:
00326       Led_usb_connected_off();
00327       break;
00328     }
00329     previous_session = device_connected;
00330     previous_vbus = vbus_state;
00331   }
00332 }
00333 
00334 
00335 
00336 //-----------------------------------------------------------------
00337 // MESSAGING FEATURES
00338 // ******************
00339 
00340 void Otg_messaging_init(void)
00341 {
00342   Led_unsupported_off();
00343   Led_noresponse_off();
00344 }
00345 
00346 // Function that get the string number as input and writes the corresponding FAILURE string on LCD
00347 void Otg_output_failure_msg(U8 str_nb)
00348 {
00349   switch (str_nb)
00350   {
00351     case OTGMSG_UNSUPPORTED:
00352       // Put here handler code for this message
00353       Led_unsupported_on();
00354       break;
00355       
00356     case OTGMSG_UNSUPPORTED_HUB:
00357       // Put here handler code for this message
00358       Led_unsupported_on();
00359       break;
00360 
00361     case OTGMSG_DEVICE_NO_RESP:
00362       // Put here handler code for this message
00363       Led_noresponse_on();
00364       break;
00365       
00366     case OTGMSG_SRP_A_NO_RESP:
00367       // Put here handler code for this message
00368       Led_noresponse_on();
00369       break;
00370       
00371     default:
00372       break;
00373   }
00374 }
00375 
00376 // Clears the line of FAILURE messages
00377 void Otg_clear_failure_message()
00378 {
00379   Led_unsupported_off();
00380   Led_noresponse_off();  
00381 }
00382 
00383 

Generated on Mon Feb 19 09:31:47 2007 for Atmel by  doxygen 1.5.1-p1