]> git.zerfleddert.de Git - fnordlicht-mini/blame - firmware/fnordlicht-controller/usb.c
reference firmware
[fnordlicht-mini] / firmware / fnordlicht-controller / usb.c
CommitLineData
ec1bef8e 1/* vim:ts=4 sts=4 et tw=80
2 *
3 * fnordlicht firmware
4 *
5 * for additional information please
6 * see http://lochraster.org/fnordlichtmini
7 *
8 * (c) by Alexander Neumann <alexander@bumpern.de>
9 *
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.
13 *
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
17 * more details.
18 *
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/>.
21 */
22
23/* includes */
24#include "globals.h"
25#include "../common/io.h"
26
27#include <stdint.h>
28#include <stdbool.h>
29
30#include "../common/common.h"
31#include "usbdrv/usbdrv.h"
32#include "timer.h"
33#include "uart.h"
34#include "ir.h"
35
36static bool usb_status;
37
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
41 * is switched off */
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); \
48 } while(0);
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); \
54 } while(0);
55#endif
56
57#define USBRQ_SEND 1
58#define USBRQ_IR_STATE 2
59#define USBRQ_IR_READ 3
60
61struct usb_state_t {
62 enum {
63 USB_STATE_IDLE = 0,
64 USB_STATE_SEND = 1,
65 } state;
66
67 usbMsgLen_t bytes_remaining;
68};
69
70struct usb_state_t usb;
71
72USB_PUBLIC usbMsgLen_t usbFunctionSetup(uchar data[8])
73{
74 usbRequest_t *req = (void *)data;
75 usbMsgLen_t len = 0;
76 static uint8_t buf[8];
77
78 /* set global data pointer to local buffer */
79 usbMsgPtr = buf;
80
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];
85 return USB_NO_MSG;
86 } else {
87 /* too long */
88 buf[0] = 1;
89 len = 1;
90 }
91 } else if (req->bRequest == USBRQ_IR_STATE) {
92 /* read or set state? */
93 if (req->bmRequestType & USBRQ_DIR_MASK) {
94 /* read */
95 buf[0] = ir_global.mode;
96 len = 1;
97 } else {
98 /* write */
99 uint8_t new_state = req->wValue.bytes[0];
100 if (new_state <= IR_RECEIVE)
101 ir_set_mode(new_state);
102 }
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;
107 }
108 }
109
110 return len;
111}
112
113uchar usbFunctionWrite(uchar *data, uchar len)
114{
115 if (len > usb.bytes_remaining)
116 len = usb.bytes_remaining;
117
118 usb.bytes_remaining -= len;
119
120 while (len--) {
121 /* ugly hack: busy wait until the fifo is ready for another byte... */
122 while (fifo_full(&global_uart.tx));
123 uart_putc(*data++);
124 }
125
126 if (usb.bytes_remaining == 0) {
127 return true;
128 usb.state == USB_STATE_IDLE;
129 } else
130 return len;
131}
132
133void usb_init(void)
134{
135 usbInit();
136}
137
138void usb_enable(void)
139{
140 usbDeviceConnect();
141 usb_status = true;
142}
143
144void usb_disable(void)
145{
146 usbDeviceDisconnect();
147 usb_status = false;
148}
149
150bool usb_enabled(void)
151{
152 return usb_status;
153}
154
155void usb_poll(void)
156{
157 if (usb_status)
158 usbPoll();
159}
Impressum, Datenschutz