1 /* vim:ts=4 sts=4 et tw=80
5 * for additional information please
6 * see http://lochraster.org/fnordlichtmini
8 * (c) by Alexander Neumann <alexander@bumpern.de>
10 * This program is free software: you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License version 3 as published by
12 * the Free Software Foundation.
14 * This program is distributed in the hope that it will be useful, but WITHOUT
15 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
19 * You should have received a copy of the GNU General Public License along with
20 * this program. If not, see <http://www.gnu.org/licenses/>.
25 #include "../common/io.h"
30 #include "../common/common.h"
31 #include "usbdrv/usbdrv.h"
36 static bool usb_status
;
38 /* supply custom usbDeviceConnect() and usbDeviceDisconnect() macros
39 * which turn the interrupt on and off at the right times,
40 * and prevent the execution of an interrupt while the pullup resistor
42 #ifdef USB_CFG_PULLUP_IOPORTNAME
43 #undef usbDeviceConnect
44 #define usbDeviceConnect() do { \
45 USB_PULLUP_DDR |= (1<<USB_CFG_PULLUP_BIT); \
46 USB_PULLUP_OUT |= (1<<USB_CFG_PULLUP_BIT); \
47 USB_INTR_ENABLE |= (1 << USB_INTR_ENABLE_BIT); \
49 #undef usbDeviceDisconnect
50 #define usbDeviceDisconnect() do { \
51 USB_INTR_ENABLE &= ~(1 << USB_INTR_ENABLE_BIT); \
52 USB_PULLUP_DDR &= ~(1<<USB_CFG_PULLUP_BIT); \
53 USB_PULLUP_OUT &= ~(1<<USB_CFG_PULLUP_BIT); \
58 #define USBRQ_IR_STATE 2
59 #define USBRQ_IR_READ 3
67 usbMsgLen_t bytes_remaining
;
70 struct usb_state_t usb
;
72 USB_PUBLIC usbMsgLen_t
usbFunctionSetup(uchar data
[8])
74 usbRequest_t
*req
= (void *)data
;
76 static uint8_t buf
[8];
78 /* set global data pointer to local buffer */
81 if (req
->bRequest
== USBRQ_SEND
&& req
->wLength
.word
> 0) {
82 usb
.state
= USB_STATE_SEND
;
83 if (req
->wLength
.word
< 256) {
84 usb
.bytes_remaining
= req
->wLength
.bytes
[0];
91 } else if (req
->bRequest
== USBRQ_IR_STATE
) {
92 /* read or set state? */
93 if (req
->bmRequestType
& USBRQ_DIR_MASK
) {
95 buf
[0] = ir_global
.mode
;
99 uint8_t new_state
= req
->wValue
.bytes
[0];
100 if (new_state
<= IR_RECEIVE
)
101 ir_set_mode(new_state
);
103 } else if (req
->bRequest
== USBRQ_IR_READ
) {
104 if (ir_global
.mode
== IR_DISABLED
) {
105 usbMsgPtr
= (void *)ir_global
.time
;
106 return 2*ir_global
.pos
;
113 uchar
usbFunctionWrite(uchar
*data
, uchar len
)
115 if (len
> usb
.bytes_remaining
)
116 len
= usb
.bytes_remaining
;
118 usb
.bytes_remaining
-= len
;
121 /* ugly hack: busy wait until the fifo is ready for another byte... */
122 while (fifo_full(&global_uart
.tx
));
126 if (usb
.bytes_remaining
== 0) {
128 usb
.state
== USB_STATE_IDLE
;
138 void usb_enable(void)
144 void usb_disable(void)
146 usbDeviceDisconnect();
150 bool usb_enabled(void)