1 /* mdebug.c
2 *
3 * Copyright 2015 Brian Swetland <swetland@frotz.net>
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18 #include <app.h>
19 #include <lk/debug.h>
20 #include <string.h>
21 #include <stdlib.h>
22 #include <printf.h>
23 #include <dev/udc.h>
24
25 #include <platform.h>
26 #include <arch/arm.h>
27 #include <kernel/thread.h>
28 #include <kernel/event.h>
29
30 #include <platform/lpc43xx-gpio.h>
31
32 #include "swd.h"
33
34 #define TX_AHEAD 1
35
36 static event_t txevt = EVENT_INITIAL_VALUE(txevt, TX_AHEAD, 0);
37 static event_t rxevt = EVENT_INITIAL_VALUE(rxevt, 0, 0);
38
39 static udc_request_t *txreq;
40 static udc_request_t *rxreq;
41 static udc_endpoint_t *txept;
42 static udc_endpoint_t *rxept;
43
44 static volatile int online;
45 static volatile int txstatus;
46 static volatile int rxstatus;
47 static volatile int rxactual;
48
mdebug_notify(udc_gadget_t * gadget,unsigned event)49 static void mdebug_notify(udc_gadget_t *gadget, unsigned event) {
50 if (event == UDC_EVENT_ONLINE) {
51 online = 1;
52 } else {
53 online = 0;
54 }
55 }
56
rx_complete(udc_request_t * req,unsigned actual,int status)57 static void rx_complete(udc_request_t *req, unsigned actual, int status) {
58 rxactual = actual;
59 rxstatus = status;
60 event_signal(&rxevt, 0);
61 }
62
tx_complete(udc_request_t * req,unsigned actual,int status)63 static void tx_complete(udc_request_t *req, unsigned actual, int status) {
64 txstatus = status;
65 event_signal(&txevt, 0);
66 }
67
68 #if TX_AHEAD
usb_xmit(void * data,unsigned len)69 void usb_xmit(void *data, unsigned len) {
70 event_wait(&txevt);
71 event_unsignal(&txevt);
72 txreq->buffer = data;
73 txreq->length = len;
74 txstatus = 1;
75 if (udc_request_queue(txept, txreq)) {
76 printf("txqf\n");
77 event_signal(&txevt, 0);
78 }
79 }
80 #else
usb_xmit(void * data,unsigned len)81 void usb_xmit(void *data, unsigned len) {
82 event_unsignal(&txevt);
83 txreq->buffer = data;
84 txreq->length = len;
85 txstatus = 1;
86 if (udc_request_queue(txept, txreq) == 0) {
87 event_wait(&txevt);
88 }
89 }
90 #endif
91
usb_recv(void * data,unsigned len)92 int usb_recv(void *data, unsigned len) {
93 event_unsignal(&rxevt);
94 rxreq->buffer = data;
95 rxreq->length = len;
96 rxstatus = 1;
97 if (udc_request_queue(rxept, rxreq)) {
98 printf("rxqf\n");
99 return -1;
100 }
101 event_wait(&rxevt);
102 return rxstatus ? rxstatus : rxactual;
103 }
104
105 static udc_device_t mdebug_device = {
106 .vendor_id = 0x1209,
107 .product_id = 0x5038,
108 .version_id = 0x0100,
109 };
110
111 static udc_endpoint_t *mdebug_endpoints[2];
112
113 static udc_gadget_t mdebug_gadget = {
114 .notify = mdebug_notify,
115 .ifc_class = 0xFF,
116 .ifc_subclass = 0xFF,
117 .ifc_protocol = 0xFF,
118 .ifc_endpoints = 2,
119 .ept = mdebug_endpoints,
120 };
121
mdebug_init(const struct app_descriptor * app)122 static void mdebug_init(const struct app_descriptor *app) {
123 swd_init();
124
125 udc_init(&mdebug_device);
126 mdebug_endpoints[0] = txept = udc_endpoint_alloc(UDC_BULK_IN, 512);
127 mdebug_endpoints[1] = rxept = udc_endpoint_alloc(UDC_BULK_OUT, 512);
128 txreq = udc_request_alloc();
129 rxreq = udc_request_alloc();
130 rxreq->complete = rx_complete;
131 txreq->complete = tx_complete;
132 udc_register_gadget(&mdebug_gadget);
133 }
134
135 void handle_rswd(void);
136 void swo_init(udc_endpoint_t *ept);
137 void swo_config(unsigned mhz);
138
mdebug_entry(const struct app_descriptor * app,void * args)139 static void mdebug_entry(const struct app_descriptor *app, void *args) {
140 udc_start();
141 swo_init(txept);
142 swo_config(6000000);
143
144 for (;;) {
145 if (!online) {
146 thread_yield();
147 continue;
148 }
149 handle_rswd();
150 }
151 }
152
153 APP_START(usbtest)
154 .init = mdebug_init,
155 .entry = mdebug_entry,
156 APP_END
157
158
159