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
1.5.1-p1