1
|
#include <stdlib.h>
|
2
|
#include <stdint.h>
|
3
|
#include <board.h>
|
4
|
#include <utility/trace.h>
|
5
|
#include <utility/led.h>
|
6
|
|
7
|
#include <usb/common/core/USBGenericRequest.h>
|
8
|
#include <usb/device/core/USBD.h>
|
9
|
#include <usb/device/core/USBDDriver.h>
|
10
|
#include <usb/device/core/USBDDriverDescriptors.h>
|
11
|
#include <usb/device/core/USBDCallbacks.h>
|
12
|
#include <usb/common/audio/AUDGenericRequest.h>
|
13
|
#include <usb/common/audio/AUDFeatureUnitRequest.h>
|
14
|
|
15
|
#include <AUDDFastSourceDescriptors.h>
|
16
|
#include <fast_source.h>
|
17
|
|
18
|
extern const USBDDriverDescriptors auddFastSourceDriverDescriptors;
|
19
|
static unsigned char driver_interfaces[3];
|
20
|
static USBDDriver fast_source_driver;
|
21
|
|
22
|
#define EP_NR 6
|
23
|
|
24
|
/* callback */
|
25
|
void USBDCallbacks_RequestReceived(const USBGenericRequest *request)
|
26
|
{
|
27
|
fastsource_req_hdlr(request);
|
28
|
}
|
29
|
|
30
|
void USBDDriverCallbacks_InterfaceSettingChanged(unsigned char interface,
|
31
|
unsigned char setting)
|
32
|
{
|
33
|
if ((interface == AUDDLoopRecDriverDescriptors_STREAMING)
|
34
|
&& (setting == 0))
|
35
|
LED_Clear(USBD_LEDOTHER);
|
36
|
else
|
37
|
LED_Set(USBD_LEDOTHER);
|
38
|
}
|
39
|
|
40
|
static void fastsource_get_feat_cur_val(uint8_t entity, uint8_t channel,
|
41
|
uint8_t control, uint8_t length)
|
42
|
{
|
43
|
/* FIXME */
|
44
|
USBD_Stall(0);
|
45
|
}
|
46
|
|
47
|
static void fastsource_set_feat_cur_val(uint8_t entity, uint8_t channel,
|
48
|
uint8_t control, uint8_t length)
|
49
|
{
|
50
|
/* FIXME */
|
51
|
USBD_Stall(0);
|
52
|
}
|
53
|
|
54
|
void fastsource_req_hdlr(const USBGenericRequest *request)
|
55
|
{
|
56
|
unsigned char entity;
|
57
|
unsigned char interface;
|
58
|
|
59
|
switch (USBGenericRequest_GetType(request)) {
|
60
|
case USBGenericRequest_STANDARD:
|
61
|
USBDDriver_RequestHandler(&fast_source_driver, request);
|
62
|
return;
|
63
|
case USBGenericRequest_CLASS:
|
64
|
/* continue below */
|
65
|
break;
|
66
|
default:
|
67
|
TRACE_WARNING("Unsupported request type %u\n\r",
|
68
|
USBGenericRequest_GetType(request));
|
69
|
USBD_Stall(0);
|
70
|
return;
|
71
|
}
|
72
|
|
73
|
switch (USBGenericRequest_GetRequest(request)) {
|
74
|
case AUDGenericRequest_SETCUR:
|
75
|
entity = AUDGenericRequest_GetEntity(request);
|
76
|
interface = AUDGenericRequest_GetInterface(request);
|
77
|
if (((entity == AUDDLoopRecDriverDescriptors_FEATUREUNIT) ||
|
78
|
(entity == AUDDLoopRecDriverDescriptors_FEATUREUNIT_REC)) &&
|
79
|
(interface == AUDDLoopRecDriverDescriptors_CONTROL)) {
|
80
|
fastsource_set_feat_cur_val(entity,
|
81
|
AUDFeatureUnitRequest_GetChannel(request),
|
82
|
AUDFeatureUnitRequest_GetControl(request),
|
83
|
USBGenericRequest_GetLength(request));
|
84
|
} else {
|
85
|
TRACE_WARNING("Unsupported entity/interface combination 0x%04x\n\r",
|
86
|
USBGenericRequest_GetIndex(request));
|
87
|
USBD_Stall(0);
|
88
|
}
|
89
|
break;
|
90
|
case AUDGenericRequest_GETCUR:
|
91
|
entity = AUDGenericRequest_GetEntity(request);
|
92
|
interface = AUDGenericRequest_GetInterface(request);
|
93
|
if (((entity == AUDDLoopRecDriverDescriptors_FEATUREUNIT) ||
|
94
|
(entity == AUDDLoopRecDriverDescriptors_FEATUREUNIT_REC)) &&
|
95
|
(interface == AUDDLoopRecDriverDescriptors_CONTROL)) {
|
96
|
fastsource_get_feat_cur_val(entity,
|
97
|
AUDFeatureUnitRequest_GetChannel(request),
|
98
|
AUDFeatureUnitRequest_GetControl(request),
|
99
|
USBGenericRequest_GetLength(request));
|
100
|
} else {
|
101
|
TRACE_WARNING("Unsupported entity/interface combination 0x%04x\n\r",
|
102
|
USBGenericRequest_GetIndex(request));
|
103
|
USBD_Stall(0);
|
104
|
}
|
105
|
break;
|
106
|
default:
|
107
|
TRACE_WARNING("Unsupported request %u\n\r",
|
108
|
USBGenericRequest_GetIndex(request));
|
109
|
USBD_Stall(0);
|
110
|
break;
|
111
|
}
|
112
|
}
|
113
|
|
114
|
void fastsource_init(void)
|
115
|
{
|
116
|
USBDDriver_Initialize(&fast_source_driver, &auddFastSourceDriverDescriptors,
|
117
|
driver_interfaces);
|
118
|
|
119
|
USBD_Init();
|
120
|
}
|
121
|
|
122
|
const uint8_t test_data[AUDDLoopRecDriver_BYTESPERFRAME] = {
|
123
|
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
124
|
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
|
125
|
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
|
126
|
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f };
|
127
|
|
128
|
static void wr_compl_cb(void *arg, unsigned char status, unsigned int transferred,
|
129
|
unsigned int remain)
|
130
|
{
|
131
|
//TRACE_INFO("COMPL: status %u transferred %u remain %u\r\n", status, transferred, remain);
|
132
|
//TRACE_INFO(".");
|
133
|
|
134
|
if (status == 0 && remain == 0) {
|
135
|
fastsource_start();
|
136
|
} else {
|
137
|
TRACE_WARNING("Err: EP%u wr_compl, status 0x%02u, xfr %u, remain %u\r\n",
|
138
|
EP_NR, status, transferred, remain);
|
139
|
}
|
140
|
}
|
141
|
|
142
|
void fastsource_start(void)
|
143
|
{
|
144
|
//TRACE_WARNING("DATA: %02x %02x %02x %02x\r\n", test_data[0], test_data[1], test_data[2], test_data[3]);
|
145
|
USBD_Write(EP_NR, test_data, sizeof(test_data), wr_compl_cb, NULL);
|
146
|
}
|
147
|
|
148
|
void fastsource_dump(void)
|
149
|
{
|
150
|
printf("usb pending: ");
|
151
|
printf("ssc pending:");
|
152
|
llist_for_each_entry_safe(rctx, rctx2, &ssc_state.pending_rctx, list)
|
153
|
printf(" %d", req_ctx_num(rctx));
|
154
|
printf("\r\n");
|
155
|
}
|