Contiki 2.5
usb_task.c
Go to the documentation of this file.
1 /* This file has been prepared for Doxygen automatic documentation generation.*/
2 /*! \file usb_task.c *********************************************************************
3  *
4  * \brief
5  * This file manages the USB task either device/host or both.
6  *
7  * The USB task selects the correct USB task (usb_device task or usb_host task
8  * to be executed depending on the current mode available.
9  *
10  * According to USB_DEVICE_FEATURE and USB_HOST_FEATURE value (located in conf_usb.h file)
11  * The usb_task can be configured to support USB DEVICE mode or USB Host mode or both
12  * for a dual role device application.
13  *
14  * This module also contains the general USB interrupt subroutine. This subroutine is used
15  * to detect asynchronous USB events.
16  *
17  * Note:
18  * - The usb_task belongs to the scheduler, the usb_device_task and usb_host do not, they are called
19  * from the general usb_task
20  * - See conf_usb.h file for more details about the configuration of this module
21  *
22  * \addtogroup usbstick
23  *
24  * \author
25  * Atmel Corporation: http://www.atmel.com \n
26  * Support email: avr@atmel.com
27  ******************************************************************************/
28 /* Copyright (c) 2008 Colin O'Flynn
29  Copyright (c) 2008 ATMEL Corporation
30  All rights reserved.
31 
32  Redistribution and use in source and binary forms, with or without
33  modification, are permitted provided that the following conditions are met:
34 
35  * Redistributions of source code must retain the above copyright
36  notice, this list of conditions and the following disclaimer.
37  * Redistributions in binary form must reproduce the above copyright
38  notice, this list of conditions and the following disclaimer in
39  the documentation and/or other materials provided with the
40  distribution.
41  * Neither the name of the copyright holders nor the names of
42  contributors may be used to endorse or promote products derived
43  from this software without specific prior written permission.
44 
45  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
46  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
47  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
48  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
49  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
50  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
51  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
52  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
53  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
54  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
55  POSSIBILITY OF SUCH DAMAGE.
56 */
57 
58 /**
59  \ingroup usbstick
60  \defgroup usbtask USB Contiki Task
61  @{
62 */
63 
64 //_____ I N C L U D E S ___________________________________________________
65 
66 #include "contiki.h"
67 #include "config.h"
68 #include "conf_usb.h"
69 #include "usb_drv.h"
70 #include "usb_descriptors.h"
71 #include "pll_drv.h"
72 #include "usb_task.h"
73 #include "rndis/rndis_protocol.h"
74 #include "rndis/rndis_task.h"
75 
76 PROCESS(usb_process, "USB process");
77 
78 #ifndef USE_USB_PADS_REGULATOR
79  #error "USE_USB_PADS_REGULATOR" should be defined as ENABLE or DISABLE in conf_usb.h file
80 #endif
81 #include <avr/sleep.h>
82 
83 //_____ M A C R O S ________________________________________________________
84 
85 #ifndef LOG_STR_CODE
86 #define LOG_STR_CODE(str)
87 #else
88 U8 code log_device_disconnect[]="Device Disconnected";
89 U8 code log_id_change[]="Pin Id Change";
90 #endif
91 
92 #define USB_EVENT 0x2F /* Contiki event number - I just made this one up?*/
93 
94 //_____ D E F I N I T I O N S ______________________________________________
95 
96 //!
97 //! Public : U16 g_usb_event
98 //! usb_connected is used to store USB events detected upon
99 //! USB general interrupt subroutine
100 //! Its value is managed by the following macros (See usb_task.h file)
101 //! Usb_send_event(x)
102 //! Usb_ack_event(x)
103 //! Usb_clear_all_event()
104 //! Is_usb_event(x)
105 //! Is_not_usb_event(x)
106 volatile uint16_t g_usb_event=0;
107 
108 
109 //!
110 //! Public : (bit) usb_connected
111 //! usb_connected is set to TRUE when VBUS has been detected
112 //! usb_connected is set to FALSE otherwise
113 //! Used with USB_DEVICE_FEATURE == ENABLED only
114 //!/
116 
117 //!
118 //! Public : (U8) usb_configuration_nb
119 //! Store the number of the USB configuration used by the USB device
120 //! when its value is different from zero, it means the device mode is enumerated
121 //! Used with USB_DEVICE_FEATURE == ENABLED only
122 //!/
123 extern U8 usb_configuration_nb;
124 
125 
126 //_____ D E C L A R A T I O N S ____________________________________________
127 
128 
129 
130 /**
131  * \brief Spare function to handle sleep mode.
132  */
133 extern void suspend_action(void)
134 {
135  Enable_interrupt();
136  set_sleep_mode(SLEEP_MODE_PWR_DOWN);
137  sleep_mode();
138 }
139 
140 /**
141  * \brief This function initializes the USB device controller
142  *
143  * This function enables the USB controller and init the USB interrupts.
144  * The aim is to allow the USB connection detection in order to send
145  * the appropriate USB event to the operating mode manager.
146  * Start device function is executed once VBUS connection has been detected
147  * either by the VBUS change interrupt either by the VBUS high level
148  */
149 void usb_start_device (void)
150 {
151  Pll_start_auto();
152  Wait_pll_ready();
153  Usb_unfreeze_clock();
154  Usb_enable_vbus_interrupt();
156  usb_init_device(); // configure the USB controller EP0
157  Usb_attach();
158 }
159 
160 
161 /**
162  * \brief USB Poll Handler
163  *
164  * This routine is repetively called, and deals with things such as new SETUP transfers
165  * on the control endpoint
166  */
167 static void pollhandler(void)
168 {
169  /* Check for setup packets */
170  Usb_select_endpoint(EP_CONTROL);
171  if (Is_usb_receive_setup()) {
173  }
174 
175  /* The previous call might have requested we send
176  out something to the RNDIS interrupt endpoint */
177  if (schedule_interrupt) {
178  Usb_select_endpoint(INT_EP);
179 
180  //Linux is a bunch of lies, and won't read
181  //the interrupt endpoint. Hence if this isn't ready just exit
182  //while(!Is_usb_write_enabled());
183 
184  if (Is_usb_write_enabled()) {
185 
186  // Only valid interrupt is:
187  // 0x00000001 0x00000000
188  //
189  Usb_write_byte(0x01);
190  Usb_write_byte(0x00);
191  Usb_write_byte(0x00);
192  Usb_write_byte(0x00);
193  Usb_write_byte(0x00);
194  Usb_write_byte(0x00);
195  Usb_write_byte(0x00);
196  Usb_write_byte(0x00);
197 
198  //Send back
199  Usb_send_in();
200 
201  schedule_interrupt = 0;
202  }
203  }
204 
205  /* Continue polling */
206  process_poll(&usb_process);
207 
208 }
209 /**
210  * \brief USB Process
211  *
212  * The actual USB process, deals with USB events such as resets, and being plugged in
213  * or unplugged. A seperate polling routine is setup, which continously checks for
214  * things such as SETUP packets on the control interface. They must be responded to
215  * very quickly, hence the need for a polling process.
216  */
217 PROCESS_THREAD(usb_process, ev, data_proc)
218 {
219 
220 PROCESS_POLLHANDLER(pollhandler());
221 
222 PROCESS_BEGIN();
223 
224 
225  /*** USB initilization ***/
226 
227  #if (USE_USB_PADS_REGULATOR==ENABLE) // Otherwise assume USB PADs regulator is not used
229  #endif
230 
232 
233  /* Init USB controller */
234  Enable_interrupt();
235  Usb_disable();
236  Usb_enable();
237  Usb_select_device();
238 #if (USB_LOW_SPEED_DEVICE==ENABLE)
240 #endif
241  Usb_enable_vbus_interrupt();
242  Enable_interrupt();
243 
244 
245  /* Ensure pollhandler is called to start it off */
246  process_poll(&usb_process);
247 
248 
249  /*** Begin actual USB process ***/
250  while(1)
251  {
252 
253  if (Is_usb_vbus_high()&& usb_connected==FALSE)
254  {
257  Usb_vbus_on_action();
258  }
259 
261  {
265  }
266 
267 
268  PROCESS_WAIT_EVENT_UNTIL(ev == USB_EVENT);
269  }//while(1)
270 
271 PROCESS_END();
272 
273 }
274 
275 
276 //! @brief USB general interrupt subroutine
277 //!
278 //! This function is called each time a USB interrupt occurs.
279 //! The following USB DEVICE events are taken in charge:
280 //! - VBus On / Off
281 //! - Start Of Frame
282 //! - Suspend
283 //! - Wake-Up
284 //! - Resume
285 //! - Reset
286 //! - Start of frame
287 //!
288 //! For each event, the user can launch an action by completing
289 //! the associate define (See conf_usb.h file to add action upon events)
290 //!
291 //! Note: Only interrupts events that are enabled are processed
292 //!
293 
294 ISR(USB_GEN_vect)
295 {
296 
297  process_post(&usb_process, USB_EVENT, NULL);
298 
299  //- VBUS state detection
300  if (Is_usb_vbus_transition() && Is_usb_vbus_interrupt_enabled())
301  {
302  Usb_ack_vbus_transition();
303  if (Is_usb_vbus_high())
304  {
306  Usb_vbus_on_action();
310  Usb_attach();
311  }
312  else
313  {
314  Usb_vbus_off_action();
318  }
319  }
320  // - Device start of frame received
321  if (Is_usb_sof() && Is_sof_interrupt_enabled())
322  {
323  Usb_ack_sof();
324  Usb_sof_action();
325  }
326  // - Device Suspend event (no more USB activity detected)
327  if (Is_usb_suspend() && Is_suspend_interrupt_enabled())
328  {
329  Usb_ack_suspend();
331  Usb_ack_wake_up(); // clear wake up to detect next event
334  Usb_suspend_action();
335  }
336  // - Wake up event (USB activity detected): Used to resume
337  if (Is_usb_wake_up() && Is_swake_up_interrupt_enabled())
338  {
339  Usb_unfreeze_clock();
340  Usb_ack_wake_up();
342  Usb_wake_up_action();
344  }
345  // - Resume state bus detection
346  if (Is_usb_resume() && Is_resume_interrupt_enabled())
347  {
349  Usb_ack_resume();
351  Usb_resume_action();
353  }
354  // - USB bus reset detection
355  if (Is_usb_reset()&& Is_reset_interrupt_enabled())
356  {
357  Usb_ack_reset();
358  usb_init_device();
359  Usb_reset_action();
361  }
362 
363 }
364 
365 /** @} */
366