version 0.1 written by Akiba, taken from here:
[chibi.git] / freakusb / usb / usb.c
blobd8446af90a731ee63bbc6d0c3122370eaf26110a
1 /*******************************************************************
2 Copyright (C) 2008 FreakLabs
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License along
15 with this program; if not, write to the Free Software Foundation, Inc.,
16 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 Please post support questions to the FreakLabs forum.
19 *******************************************************************/
20 /*!
21 \defgroup usb USB
22 \file usb.c
23 \ingroup usb
25 /*******************************************************************/
26 #include "freakusb.h"
28 static usb_pcb_t pcb;
30 /**************************************************************************/
31 /*!
32 Initialize the USB stack. Actually, we just clear out the protocol control
33 block for now.
35 /**************************************************************************/
36 void usb_init()
38 memset(&pcb, 0, sizeof(usb_pcb_t));
41 /**************************************************************************/
42 /*!
43 Get a pointer to the USB stack's protocol control block.
45 /**************************************************************************/
46 usb_pcb_t *usb_pcb_get()
48 return &pcb;
51 /**************************************************************************/
52 /*!
53 Register the class driver
55 /**************************************************************************/
56 void usb_reg_class_drvr(void (*class_init)(),
57 void (*class_req_handler)(req_t *req),
58 void (*class_rx_handler)())
60 pcb.class_req_handler = class_req_handler;
61 pcb.class_init = class_init;
62 pcb.class_rx_handler = class_rx_handler;
65 /**************************************************************************/
66 /*!
67 This function needs to be polled in the main loop. It will check if there
68 are any transfers pending in either the IN or OUT direction as well as if
69 there are any pending CONTROL transfers.
71 /**************************************************************************/
72 void usb_poll()
74 U8 ep_num;
76 if (pcb.connected)
78 // if any setup data is pending, send it to the ctrl handler. we operate
79 // the ctrl fifo like a standard buffer instead of a fifo. it makes the
80 // operations easier because we can just do a pointer overlay on the buffer.
81 if (pcb.flags & (1<<SETUP_DATA_AVAIL))
83 // clear the setup flag at the very beginning. later on, we can wait
84 // on this flag if there are data stages to the setup transaction.
85 pcb.flags &= ~(1<<SETUP_DATA_AVAIL);
87 // handle the request
88 ctrl_handler();
89 usb_buf_clear_fifo(EP_CTRL);
92 // don't handle any data transfers on endpoints other than the control endpoint
93 // unless the USB is properly enumerated.
94 if (pcb.flags & (1<<ENUMERATED))
96 // if any rx data is pending, send it to the rx handler
97 if (pcb.flags & (1<<RX_DATA_AVAIL))
99 if (pcb.class_rx_handler)
101 pcb.class_rx_handler();
104 // clear the rx data avail flag now that we're done processing the rx data.
105 pcb.flags &= ~(1 << RX_DATA_AVAIL);
108 // if any tx data is pending, send it to the endpoint fifo
109 if (pcb.flags & (1<<TX_DATA_AVAIL))
111 // get the ep number of any fifo with pending tx data
112 if ((ep_num = usb_buf_data_pending(DIR_IN)) != 0xFF)
114 // disable the interrupts while we're handling endpoint data
115 // or else we might get data coming into the fifo from a non-USB related interrupt
116 // as we're reading it out of the fifo.
117 hw_intp_disable();
118 ep_write(ep_num);
119 hw_intp_enable();
121 pcb.flags &= ~(1<<TX_DATA_AVAIL);