source: azure_iot_hub_riscv/trunk/asp_baseplatform/gdic/usb_otg/dwc2_device_driver.c@ 453

Last change on this file since 453 was 453, checked in by coas-nagasima, 4 years ago

ファイルを追加

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc;charset=UTF-8
File size: 13.9 KB
Line 
1/*
2 * TOPPERS BASE PLATFORM MIDDLEWARE
3 *
4 * Copyright (C) 2017-2018 by TOPPERS PROJECT
5 * Educational Working Group.
6 *
7 * 上記著作権者は,以下の(1)~(4)の条件を満たす場合に限り,本ソフトウェ
8 * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
9 * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
10 * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
11 * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
12 * スコード中に含まれていること.
13 * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
14 * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
15 * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
16 * の無保証規定を掲載すること.
17 * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
18 * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
19 * と.
20 * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
21 * 作権表示,この利用条件および下記の無保証規定を掲載すること.
22 * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
23 * 報告すること.
24 * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
25 * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
26 * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
27 * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
28 * 免責すること.
29 *
30 * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
31 * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
32 * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
33 * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
34 * の責任を負わない.
35 *
36 * @(#) $Id$
37 */
38/*
39 * USB DEVICE HIGH DRIVERS
40 */
41
42#include "kernel_impl.h"
43#include <t_syslog.h>
44#include <t_stdlib.h>
45#include <sil.h>
46#include <target_syssvc.h>
47#include "device.h"
48
49#include "stdlib.h"
50#include "tusbd_base.h"
51#include "usb_otg.h"
52
53#define sil_orw_mem(a, b) sil_wrw_mem((a), sil_rew_mem(a) | (b))
54#define sil_andw_mem(a, b) sil_wrw_mem((a), sil_rew_mem(a) & ~(b))
55
56#ifndef MAX_DEVICE_EPS
57#define MAX_DEVICE_EPS (MAX_EPS_CHANNELS-1)
58#endif
59
60/*
61 * SETUPSTAGE CALLBACK関数
62 */
63static void
64tusbdSetupStageCallback(USB_OTG_Handle_t *husb)
65{
66 tusbdSetSpeed(husb->pDev, usbo_getDevSpeed(husb));
67 tusbdSetupStage(husb->pDev, (uint8_t *)husb->Setup);
68}
69
70/*
71 * DATAOUTSTAGE CALLBACK関数
72 */
73static void
74tusbdDataOutStageCallback(USB_OTG_Handle_t *husb, uint8_t epnum)
75{
76 tusbdDataOutStage(husb->pDev, epnum, husb->OUT_ep[epnum].xfer_buff);
77}
78
79/*
80 * DATAINSTAGE CALLBACK関数
81 */
82static void
83tusbdDataInStageCallback(USB_OTG_Handle_t *husb, uint8_t epnum)
84{
85 tusbdDataInStage(husb->pDev, epnum, husb->IN_ep[epnum].xfer_buff);
86}
87
88/*
89 * DEVICE RESET CALLBACK関数
90 */
91static void
92tusbdResetCallback(USB_OTG_Handle_t *husb)
93{
94 uint8_t speed = USB_DEVICE_SPEED_FULL;
95
96 /* Set USB Current Speed */
97 switch(husb->Init.speed){
98 case USB_SPEED_HIGH:
99 speed = USB_DEVICE_SPEED_HIGH;
100 break;
101 case USB_SPEED_FULL:
102 speed = USB_DEVICE_SPEED_FULL;
103 break;
104 default:
105 speed = USB_DEVICE_SPEED_FULL;
106 break;
107 }
108
109 /*
110 * DEVICEのリセット
111 */
112 tusbdReset(husb->pDev);
113 tusbdSetSpeed(husb->pDev, speed);
114}
115
116/*
117 * DEVICE SUSPEND CALLBACK関数
118 */
119static void
120tusbdSuspendCallback(USB_OTG_Handle_t *husb)
121{
122 tusbdSuspend(husb->pDev);
123#if 1 /* ROI DEBUG */
124 syslog_0(LOG_NOTICE, "## tusbdSuspendCallback ##");
125#endif
126}
127
128/*
129 * DEVICE RESUME CALLBACK関数
130 */
131static void
132tusbdResumeCallback(USB_OTG_Handle_t *husb)
133{
134 tusbdResume(husb->pDev);
135#if 1 /* ROI DEBUG */
136 syslog_0(LOG_NOTICE, "## tusbdResumeCallback ##");
137#endif
138}
139
140/*
141 * ISOOUTCOMPLETE CALLBACK関数
142 */
143static void
144tusbdISOOUTIncompleteCallback(USB_OTG_Handle_t *husb, uint8_t epnum)
145{
146 tusbdIsoOutIncomplete(husb->pDev, epnum);
147}
148
149/*
150 * ISOINCOMPLETE CALLBACK関数
151 */
152static void
153tusbdISOINIncompleteCallback(USB_OTG_Handle_t *husb, uint8_t epnum)
154{
155 tusbdIsoInIncomplete(husb->pDev, epnum);
156}
157
158/*
159 * DEVICE CONNECT CALLBACK関数
160 */
161static void
162tusbdConnectCallback(USB_OTG_Handle_t *husb)
163{
164 tusbdDeviceConnected(husb->pDev);
165}
166
167/*
168 * DEVICE DISCONNECT CALLBACK関数
169 */
170static void
171tusbdDisconnectCallback(USB_OTG_Handle_t *husb)
172{
173 tusbdDeviceDisconnected(husb->pDev);
174}
175
176/*
177 * ENDPOINT取得
178 */
179static USB_OTG_EPTypeDef *
180tusbdGetEndpoint(USB_OTG_Handle_t *husb, uint8_t addr)
181{
182 USB_OTG_EPTypeDef *ep;
183
184 if((addr & USB_DEVICE_TO_HOST) != 0){
185 ep = &husb->IN_ep[addr & 0x7F];
186 }
187 else{
188 ep = &husb->OUT_ep[addr & 0x7F];
189 }
190 ep->num = addr & 0x7F;
191 ep->is_in = (USB_DEVICE_TO_HOST & addr) != 0;
192 return ep;
193}
194
195
196/*
197 * USB_OTG DWC2 HIGH DRIVER INITIALIZE
198 * parameter1 pdevice: USBデバイスハンドラ
199 * return TUSBD_ERCODE
200 */
201TUSBD_ERCODE
202dwc2_device_init(TUSBD_Handle_t *pdevice)
203{
204 USB_OTG_Handle_t *husb = (USB_OTG_Handle_t *)(pdevice->pSysData);
205 uint32_t i = 0;
206
207 /*
208 * USBハンドラに、USBデバイスハンドラをセット
209 */
210 husb->pDev = pdevice;
211
212 /*
213 * コールバック関数をセット
214 */
215 husb->devsetupstagecallback = tusbdSetupStageCallback;
216 husb->devdataoutstagecallback = tusbdDataOutStageCallback;
217 husb->devdatainstagecallback = tusbdDataInStageCallback;
218 husb->devsofcallback = NULL;
219 husb->devresetcallback = tusbdResetCallback;
220 husb->devsuspendcallback = tusbdSuspendCallback;
221 husb->devresumecallback = tusbdResumeCallback;
222 husb->devisooutcallback = tusbdISOOUTIncompleteCallback;
223 husb->devisoincallback = tusbdISOINIncompleteCallback;
224 husb->devconnectcallback = tusbdConnectCallback;
225 husb->devdisconnectcallback = tusbdDisconnectCallback;
226 husb->devlpmcallback = NULL;
227
228 /*
229 * エンドポイントの初期化
230 */
231 for(i = 0 ; i < MAX_DEVICE_EPS ; i++){
232 husb->IN_ep[i].is_in = 1;
233 husb->IN_ep[i].num = i;
234 husb->IN_ep[i].tx_fifo_num = i;
235 husb->IN_ep[i].type = EP_TYPE_CTRL;
236 husb->IN_ep[i].maxpacket = 0;
237 husb->IN_ep[i].xfer_buff = 0;
238 husb->IN_ep[i].xfer_len = 0;
239
240 husb->OUT_ep[i].is_in = 0;
241 husb->OUT_ep[i].num = i;
242 husb->OUT_ep[i].tx_fifo_num = 0;
243 husb->OUT_ep[i].type = EP_TYPE_CTRL;
244 husb->OUT_ep[i].maxpacket = 0;
245 husb->OUT_ep[i].xfer_buff = 0;
246 husb->OUT_ep[i].xfer_len = 0;
247 }
248
249 /*
250 * USBデバイスの初期化
251 */
252 usbo_devinit(husb);
253
254 /*
255 * LPMの有効化
256 */
257 usbo_init_lpm(husb);
258 return TUSBD_E_OK;
259}
260
261/*
262 * USB_OTG DWC2 HIGH DRIVER DE-INITIALIZE
263 * parameter1 pdevice: USBデバイスハンドラ
264 * return TUSBD_ERCODE
265 */
266TUSBD_ERCODE
267dwc2_device_deinit(TUSBD_Handle_t *pdevice)
268{
269 /*
270 * デバイス停止
271 */
272 dwc2_device_stop(pdevice);
273
274 /*
275 * デバイスハードウェア終了
276 */
277 usbo_deinit(pdevice->pSysData);
278 return TUSBD_E_OK;
279}
280
281/*
282 * USB_OTG DWC2 HIGH DRIVER START
283 * parameter1 pdevice: USBデバイスハンドラ
284 * return TUSBD_ERCODE
285 */
286TUSBD_ERCODE
287dwc2_device_start(TUSBD_Handle_t *pdevice)
288{
289 usbo_devconnect(pdevice->pSysData);
290 dly_tsk(3);
291 usbo_enableglobalint(pdevice->pSysData);
292 return TUSBD_E_OK;
293}
294
295/*
296 * USB_OTG DWC2 HIGH DRIVER STOP
297 * parameter1 pdevice: USBデバイスハンドラ
298 * return TUSBD_ERCODE
299 */
300TUSBD_ERCODE
301dwc2_device_stop(TUSBD_Handle_t *pdevice)
302{
303 usbo_disableglobalint(pdevice->pSysData);
304 usbo_stopdevice(pdevice->pSysData);
305 usbo_devdisconnect(pdevice->pSysData);
306 return TUSBD_E_OK;
307}
308
309/*
310 * USB_OTG DWC2 HIGH DRIVER OPEN ENDPOINT
311 * parameter1 pdevice: USBデバイスハンドラ
312 * parameter2 addr: endpointアドレス
313 * parameter3 type: endpointタイプ
314 * parameter4 mps: MAX PACKET SIZE
315 * return TUSBD_ERCODE
316 */
317TUSBD_ERCODE
318dwc2_device_openep(TUSBD_Handle_t *pdevice, uint8_t addr, uint8_t type, uint16_t mps)
319{
320 USB_OTG_Handle_t *husb = pdevice->pSysData;
321 USB_OTG_EPTypeDef *ep;
322
323 ep = tusbdGetEndpoint(husb, addr);
324 ep->maxpacket = mps;
325 ep->type = type;
326 if(ep->is_in){
327 /* 送信FIFO設定 */
328 ep->tx_fifo_num = ep->num;
329 }
330
331 /*
332 * DATA PIDの初期化
333 */
334 if (type == EP_TYPE_BULK){
335 ep->data_pid_start = 0;
336 }
337
338 usbo_activateEndpoint(husb, ep);
339 return TUSBD_E_OK;
340}
341
342/*
343 * USB_OTG DWC2 HIGH DRIVER CLOSE ENDPOINT
344 * parameter1 pdevice: USBデバイスハンドラ
345 * parameter2 addr: endpointアドレス
346 * return TUSBD_ERCODE
347 */
348TUSBD_ERCODE
349dwc2_device_closeep(TUSBD_Handle_t *pdevice, uint8_t addr)
350{
351 USB_OTG_Handle_t *husb = pdevice->pSysData;
352 USB_OTG_EPTypeDef *ep;
353
354 ep = tusbdGetEndpoint(husb, addr);
355 usbo_deactivateEndpoint(husb, ep);
356 return TUSBD_E_OK;
357}
358
359/*
360 * USB_OTG DWC2 HIGH DRIVER FLUSH ENDPOINT
361 * parameter1 pdevice: USBデバイスハンドラ
362 * parameter2 addr: endpointアドレス
363 * return TUSBD_ERCODE
364 */
365TUSBD_ERCODE
366dwc2_device_flushep(TUSBD_Handle_t *pdevice, uint8_t addr)
367{
368 USB_OTG_Handle_t *husb = pdevice->pSysData;
369
370 if((addr & USB_DEVICE_TO_HOST) != 0){
371 usbo_flushTxFifo(husb, addr & 0x7F);
372 }
373 else{
374 usbo_flushRxFifo(husb);
375 }
376 return TUSBD_E_OK;
377}
378
379/*
380 * USB_OTG DWC2 HIGH DRIVER STALL ENDPOINT
381 * parameter1 pdevice: USBデバイスハンドラ
382 * parameter2 addr: endpointアドレス
383 * return TUSBD_ERCODE
384 */
385TUSBD_ERCODE
386dwc2_device_stallep(TUSBD_Handle_t *pdevice, uint8_t addr)
387{
388 USB_OTG_Handle_t *husb = pdevice->pSysData;
389 USB_OTG_EPTypeDef *ep;
390
391 ep = tusbdGetEndpoint(husb, addr);
392 ep->is_stall = 1;
393
394 usbo_epsetStall(husb, ep);
395 if((addr & 0x7FU) == 0U){
396 usbo_ep0_outstart(husb, (uint8_t *)husb->Setup);
397 }
398 return TUSBD_E_OK;
399}
400
401/*
402 * USB_OTG DWC2 HIGH DRIVER CLEAR STALL-ENDPOINT
403 * parameter1 pdevice: USBデバイスハンドラ
404 * parameter2 addr: endpointアドレス
405 * return TUSBD_ERCODE
406 */
407TUSBD_ERCODE
408dwc2_device_clearep(TUSBD_Handle_t *pdevice, uint8_t addr)
409{
410 USB_OTG_Handle_t *husb = pdevice->pSysData;
411 USB_OTG_EPTypeDef *ep;
412
413 ep = tusbdGetEndpoint(husb, addr);
414 ep->is_stall = 0;
415
416 usbo_epclearStall(husb, ep);
417 return TUSBD_E_OK;
418}
419
420/*
421 * USB_OTG DWC2 HIGH DRIVER GET STALL CONDITION
422 * parameter1 pdevice: USBデバイスハンドラ
423 * parameter2 addr: endpointアドレス
424 * return 1:stall 0:not stall
425 */
426uint8_t
427dwc2_device_getstallcondition(TUSBD_Handle_t *pdevice, uint8_t addr)
428{
429 USB_OTG_Handle_t *husb = pdevice->pSysData;
430
431 if((addr & USB_DEVICE_TO_HOST) != 0)
432 return husb->IN_ep[addr & 0x7F].is_stall;
433 else
434 return husb->OUT_ep[addr & 0x7F].is_stall;
435}
436
437/*
438 * USB_OTG DWC2 HIGH DRIVER TRANSMIT A DATA
439 * parameter1 pdevice: USBデバイスハンドラ
440 * parameter2 addr: endpointアドレス
441 * parameter3 pbuf: 送信データバッファ
442 * parameter4 size: 送信サイズ
443 * return TUSBD_ERCODE
444 */
445TUSBD_ERCODE
446dwc2_device_transmitdata(TUSBD_Handle_t *pdevice, uint8_t addr, uint8_t *pbuf, uint16_t size)
447{
448 USB_OTG_Handle_t *husb = pdevice->pSysData;
449 USB_OTG_EPTypeDef *ep;
450
451 ep = tusbdGetEndpoint(husb, (addr | USB_DEVICE_TO_HOST));
452
453 /*
454 * 送信データ設定
455 */
456 ep->xfer_buff = pbuf;
457 ep->xfer_len = size;
458 ep->xfer_count = 0;
459
460 if(husb->Init.dma_enable == 1)
461 ep->dma_addr = (uint32_t)pbuf;
462
463 if((addr & 0x7F) == 0U){
464 usbo_ep0startxfer(husb, ep);
465 }
466 else{
467 usbo_epstartxfer(husb, ep);
468 }
469 return TUSBD_E_OK;
470}
471
472/*
473 * USB_OTG DWC2 HIGH DRIVER START to RECEIVE
474 * parameter1 pdevice: USBデバイスハンドラ
475 * parameter2 addr: endpointアドレス
476 * parameter3 pbuf: 受信データバッファ
477 * parameter4 size: 受信サイズ
478 * return TUSBD_ERCODE
479 */
480TUSBD_ERCODE
481dwc2_device_startreceive(TUSBD_Handle_t *pdevice, uint8_t addr, uint8_t *pbuf, uint16_t size)
482{
483 USB_OTG_Handle_t *husb = pdevice->pSysData;
484 USB_OTG_EPTypeDef *ep;
485
486 ep = tusbdGetEndpoint(husb, (addr & ~USB_DEVICE_TO_HOST));
487
488 /*
489 * 受信データ設定
490 */
491 ep->xfer_buff = pbuf;
492 ep->xfer_len = size;
493 ep->xfer_count = 0;
494
495 if(husb->Init.dma_enable == 1)
496 ep->dma_addr = (uint32_t)pbuf;
497
498 if((addr & 0x7F) == 0){
499 usbo_ep0startxfer(husb, ep);
500 }
501 else{
502 usbo_epstartxfer(husb, ep);
503 }
504 return TUSBD_E_OK;
505}
506
507/*
508 * USB_OTG DWC2 HIGH DRIVER TEST MODE
509 * parameter1 pdevice: USBデバイスハンドラ
510 * return TUSBD_ERCODE
511 */
512TUSBD_ERCODE
513dwc2_device_testmode(TUSBD_Handle_t *pdevice)
514{
515 return TUSBD_E_OK;
516}
517
518#ifndef TOPPERS_MPCORE
519/*
520 * USB_OTG DWC2 HIGH DRIVER REMOTE WAKEUP
521 * parameter1 pdevice: USBデバイスハンドラ
522 * return TUSBD_ERCODE
523 */
524void
525dwc2_device_wakeup(USBD_HandleTypeDef *pdevice)
526{
527 USB_OTG_Handle_t *husb = pdevice->pSysData;
528
529 if(pdevice->dev_remote_wakeup == 1 && pdevice->dev_state == TUSBD_STATE_SUSPENDED){
530 if(husb->Init.low_power_enable){
531 /* Reset SLEEPDEEP bit of Cortex System Control Register */
532 sil_andw_mem((uint32_t *)(TADR_SCB_BASE+TOFF_SCB_SCR), (SCB_SCR_SLEEPDEEP_Msk | SCB_SCR_SLEEPONEXIT_Msk));
533 sysclock_config(1);
534 }
535
536 /* Ungate PHY clock */
537 sil_andw_mem((uint32_t *)(USBPGC_BASE(husb->base)), USB_OTG_PCGCCTL_STOPCLK);
538
539 /* Activate Remote wakeup */
540 if((sil_rew_mem((uint32_t *)(USBD_BASE(husb->base)+TOFF_USBD_DSTS)) & USB_OTG_DSTS_SUSPSTS) != 0){
541 /* Activate Remote wakeup signaling */
542 sil_orw_mem((uint32_t *)(USBD_BASE(husb->base)+TOFF_USBD_DCTL), USB_OTG_DCTL_RWUSIG);
543 }
544
545 /* Remote wakeup delay */
546 sil_dly_nse(10*1000*1000);
547
548 /* Disable Remote wakeup */
549 sil_andw_mem((uint32_t *)(USBD_BASE(husb->base)+TOFF_USBD_DCTL), USB_OTG_DCTL_RWUSIG);
550
551 /* change state to configured */
552 pdevice->dev_state = TUSBD_STATE_CONFIGURED;
553
554 /* Change remote_wakeup feature to 0*/
555 pdevice->dev_remote_wakeup = 0;
556 }
557}
558#endif /* TOPPERS_MPCORE */
559
Note: See TracBrowser for help on using the repository browser.