source: azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/usb_otg/dwc2_host_driver.c@ 457

Last change on this file since 457 was 457, 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: 11.7 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 HOST HIGH DRIVERS
40 */
41
42#include "tusbh_base.h"
43#include "kernel_cfg.h"
44#include "usb_otg.h"
45
46/*
47 * URBの変換テーブル
48 */
49static const uint8_t urb_table[8] = {
50 TUSBH_URB_IDLE,
51 TUSBH_URB_DONE,
52 TUSBH_URB_NOTREADY,
53 TUSBH_URB_NYET,
54 TUSBH_URB_ERROR,
55 TUSBH_URB_STALL,
56 TUSBH_URB_ERROR,
57 TUSBH_URB_ERROR
58};
59
60/*
61 * USB HOST CLASS リンク関数
62 */
63__attribute__((weak)) void tusbhLinkHID(TUSBH_Handle_t *phost)
64{
65}
66
67__attribute__((weak)) void tusbhLinkMSC(TUSBH_Handle_t *phost)
68{
69}
70
71__attribute__((weak)) void tusbhLinkSERIAL(TUSBH_Handle_t *phost)
72{
73}
74
75__attribute__((weak)) void tusbhLinkPRT(TUSBH_Handle_t *phost)
76{
77}
78
79__attribute__((weak)) void tusbhLinkBLUETOOTH(TUSBH_Handle_t *phost)
80{
81}
82
83__attribute__((weak)) void tusbhLinkHUB(TUSBH_Handle_t *phost)
84{
85}
86
87
88
89#ifdef TOPPERS_MPCORE
90/*
91 * IDCHANGE CALLBACK関数
92 */
93static void
94dwc2_host_idchangecallback(USB_OTG_Handle_t *hhcd)
95{
96 tusbiSendData(((TUSBH_Handle_t *)(hhcd->pHost))->connect_event, TUSBH_IDCHANGE_EVENT, 0, 1, 0);
97}
98#endif /* TOPPERS_MPCORE */
99
100/*
101 * CONNECT CALLBACK関数
102 */
103static void
104dwc2_host_connectcallback(USB_OTG_Handle_t *hhcd)
105{
106 tusbiSendData(((TUSBH_Handle_t *)(hhcd->pHost))->connect_event, TUSBH_CONNECT_EVENT, 0, 1, 0);
107}
108
109/*
110 * DISCONNECT CALLBACK関数
111 */
112static void
113dwc2_host_disconnectcallback(USB_OTG_Handle_t *hhcd)
114{
115 tusbiSendData(((TUSBH_Handle_t *)(hhcd->pHost))->connect_event, TUSBH_DISCONNECT_EVENT, 0, 1, 0);
116}
117
118/*
119 * URB CHANGE CALLBACK関数
120 */
121static void
122dwc2_host_changeurbcallback(USB_OTG_Handle_t *hhcd, uint8_t chnum, uint8_t urb_state)
123{
124 TUSBH_Handle_t *phost = hhcd->pHost;
125 uint8_t urb;
126
127 if(urb_state < 8)
128 urb = urb_table[urb_state];
129 else
130 urb = TUSBH_URB_ERROR;
131 tusbiSendData(phost->process_event, TUSBH_URB_EVENT, phost->pipes[chnum].index, chnum, urb);
132}
133
134
135/*
136 * USB_OTG DWC2 HIGH DRIVER INITIALIZE
137 * parameter1 phost: USBホストハンドラ
138 * return TUSBH_ERCODE
139 */
140TUSBH_ERCODE
141dwc2_host_init(TUSBH_Handle_t *phost)
142{
143 USB_OTG_Handle_t *husb = (USB_OTG_Handle_t *)(phost->pSysData);
144
145 /*
146 * RTOSリソース設定
147 */
148 phost->processTaskID = TUSBH_P_TASK;
149 phost->eventTaskID = TUSBH_E_TASK;
150 phost->process_event = USBH_EVT1_DTQ;
151 phost->connect_event = USBH_EVT2_DTQ;
152 phost->numPipes = husb->Init.host_channels;
153
154 /*
155 * USB-OTGドライバ設定
156 */
157 husb->pHost = phost;
158
159 /*
160 * コールバック関数設定
161 */
162#ifdef TOPPERS_MPCORE
163 husb->otgidchangecallback = dwc2_host_idchangecallback;
164#endif /* TOPPERS_MPCORE */
165 husb->hostsofcallback = NULL;
166 husb->hostconnectcallback = dwc2_host_connectcallback;
167 husb->hostdisconnectcallback = dwc2_host_disconnectcallback;
168 husb->hostchangeurbcallback = dwc2_host_changeurbcallback;
169
170 /*
171 * USB-OTG初期化
172 */
173 usbo_hostinit(husb);
174
175 /*
176 * USBホストクラスのリンク
177 */
178 tusbhLinkHID(phost);
179 tusbhLinkMSC(phost);
180 tusbhLinkSERIAL(phost);
181 tusbhLinkPRT(phost);
182 tusbhLinkBLUETOOTH(phost);
183 tusbhLinkHUB(phost);
184 return TUSBH_E_OK;
185}
186
187/*
188 * USB_OTG DWC2 HIGH DRIVER DE-INITIALIZE
189 * parameter1 phost: USBホストハンドラ
190 * return TUSBH_ERCODE
191 */
192TUSBH_ERCODE
193dwc2_host_deinit(TUSBH_Handle_t *phost)
194{
195 USB_OTG_Handle_t *husb = phost->pSysData;
196
197 /*
198 * USB-OTG終了処理
199 */
200 usbo_deinit(husb);
201
202#if 0 /* ROI DEBUG クロック停止なので意味がない */
203 usbo_disableglobalint(husb);
204#endif /* ROI DEBUG */
205 return TUSBH_E_OK;
206}
207
208/*
209 * USB_OTG DWC2 HIGH DRIVER START
210 * parameter1 phost: USBホストハンドラ
211 * return TUSBH_ERCODE
212 */
213TUSBH_ERCODE
214dwc2_host_start(TUSBH_Handle_t *phost)
215{
216 usbo_starthost(phost->pSysData);
217 usbo_enableglobalint(phost->pSysData);
218 return TUSBH_E_OK;
219}
220
221/*
222 * USB_OTG DWC2 HIGH DRIVER GET SPEED
223 * parameter1 phost: USBホストハンドラ
224 * return usb speed value
225 */
226uint8_t
227dwc2_host_getspeed(TUSBH_Handle_t *phost)
228{
229 uint8_t speed = USB_DEVICE_SPEED_FULL;
230
231 switch(usbo_gethostspeed(phost->pSysData)){
232 case 0:
233 speed = USB_DEVICE_SPEED_HIGH;
234 break;
235 case 2:
236 speed = USB_DEVICE_SPEED_LOW;
237 break;
238 case 1:
239 default:
240 speed = USB_DEVICE_SPEED_FULL;
241 break;
242 }
243 return speed;
244}
245
246/*
247 * USB_OTG DWC2 HIGH DRIVER OPEN PIPE
248 * parameter1 phost: USBホストハンドラ
249 * parameter2 pipe: PIPE#
250 * parameter3 epnum: EP番号
251 * parameter4 dev_addr:デバイスアドレス
252 * parameter5 speed: デバイススピード
253 * parameter6 type: エンドポイントタイプ
254 * parameter7 eps: MAXパケットサイズ
255 * return TUSBH_ERCODE
256 */
257TUSBH_ERCODE
258dwc2_host_openpipe(TUSBH_Handle_t *phost, uint8_t pipe, uint8_t epnum, uint8_t dev_addr,
259 uint8_t speed, uint8_t type, uint16_t mps)
260{
261 USB_OTG_Handle_t *husb = (USB_OTG_Handle_t *)(phost->pSysData);
262 USB_OTG_HCTypeDef *phc = &husb->hc[pipe];
263
264 phc->dev_addr = dev_addr;
265 phc->max_packet = mps;
266 phc->ch_num = pipe;
267 phc->ep_type = type;
268 phc->ep_num = epnum & 0x7F;
269 phc->ep_is_in = ((epnum & 0x80) == 0x80);
270 phc->speed = speed;
271
272 if(usbo_hc_init(husb, pipe, epnum) == E_OK)
273 return TUSBH_E_OK;
274 else
275 return TUSBH_E_ERR;
276}
277
278/*
279 * USB_OTG DWC2 HIGH DRIVER CLOSE PIPE
280 * parameter1 phost: USBホストハンドラ
281 * parameter2 pipe: PIPE#
282 * return TUSBH_ERCODE
283 */
284TUSBH_ERCODE
285dwc2_host_closepipe(TUSBH_Handle_t *phost, uint8_t pipe)
286{
287 loc_cpu();
288 usbo_hc_halt(phost->pSysData, pipe);
289 unl_cpu();
290 return TUSBH_E_OK;
291}
292
293/*
294 * USB_OTG DWC2 HIGH DRIVER SUBMIT URB
295 * parameter1 phost: USBホストハンドラ
296 * parameter2 pipe: PIPE#
297 * parameter3 dir: 接続方向:0Out/1:In
298 * parameter4 token: エンドポイント設定タイプ:0:SETUP/1:DATA
299 * parameter5 pbuff: 通信領域へのポインタ
300 * parameter6 length: 通信サイズ
301 * parameter7 do_ping: DO PING設定
302 * return TUSBH_ERCODE
303 */
304TUSBH_ERCODE
305dwc2_host_submiturb(TUSBH_Handle_t *phost, uint8_t pipe, uint8_t dir,
306 uint8_t token, uint8_t* pbuff, uint16_t length, uint8_t do_ping)
307{
308 USB_OTG_Handle_t *husb = (USB_OTG_Handle_t *)phost->pSysData;
309
310#ifdef TOPPERS_MPCORE
311 usbo_dma_wait(husb, pipe);
312#endif /* TOPPERS_MPCORE */
313 husb->hc[pipe].ep_is_in = dir;
314
315 if(token == 0)
316 husb->hc[pipe].data_pid = HC_PID_SETUP;
317 else
318 husb->hc[pipe].data_pid = HC_PID_DATA1;
319
320 /* Manage Data Toggle */
321 switch(husb->hc[pipe].ep_type){
322 case EP_TYPE_CTRL:
323 if(token == 1 && dir == 0){ /*send data */
324 if(length == 0){ /* For Status OUT stage, Length==0, Status Out PID = 1 */
325 husb->hc[pipe].toggle_out = 1;
326 }
327
328 /* Set the Data Toggle bit as per the Flag */
329 if(husb->hc[pipe].toggle_out == 0){ /* Put the PID 0 */
330 husb->hc[pipe].data_pid = HC_PID_DATA0;
331 }
332 else{ /* Put the PID 1 */
333 husb->hc[pipe].data_pid = HC_PID_DATA1;
334 }
335 if(husb->hc[pipe].urb_state != URB_NOTREADY){
336 husb->hc[pipe].do_ping = do_ping;
337 }
338 }
339 break;
340
341 case EP_TYPE_BULK:
342 if(dir == 0){
343 /* Set the Data Toggle bit as per the Flag */
344 if(husb->hc[pipe].toggle_out == 0){ /* Put the PID 0 */
345 husb->hc[pipe].data_pid = HC_PID_DATA0;
346 }
347 else{ /* Put the PID 1 */
348 husb->hc[pipe].data_pid = HC_PID_DATA1;
349 }
350 if(husb->hc[pipe].urb_state != URB_NOTREADY){
351 husb->hc[pipe].do_ping = do_ping;
352 }
353 }
354 else{
355 if(husb->hc[pipe].toggle_in == 0){
356 husb->hc[pipe].data_pid = HC_PID_DATA0;
357 }
358 else{
359 husb->hc[pipe].data_pid = HC_PID_DATA1;
360 }
361 }
362 break;
363 case EP_TYPE_INTR:
364 if(dir == 0){
365 /* Set the Data Toggle bit as per the Flag */
366 if(husb->hc[pipe].toggle_out == 0){ /* Put the PID 0 */
367 husb->hc[pipe].data_pid = HC_PID_DATA0;
368 }
369 else{ /* Put the PID 1 */
370 husb->hc[pipe].data_pid = HC_PID_DATA1;
371 }
372 }
373 else{
374 if(husb->hc[pipe].toggle_in == 0){
375 husb->hc[pipe].data_pid = HC_PID_DATA0;
376 }
377 else{
378 husb->hc[pipe].data_pid = HC_PID_DATA1;
379 }
380 }
381 break;
382 case EP_TYPE_ISOC:
383 husb->hc[pipe].data_pid = HC_PID_DATA0;
384 break;
385 }
386
387 husb->hc[pipe].xfer_buff = pbuff;
388 husb->hc[pipe].xfer_len = length;
389 husb->hc[pipe].urb_state = URB_IDLE;
390 husb->hc[pipe].xfer_count = 0;
391 husb->hc[pipe].ch_num = pipe;
392 husb->hc[pipe].state = USBO_HC_IDLE;
393
394 usbo_hc_startxfer(husb, pipe);
395 return TUSBH_E_OK;
396}
397
398/*
399 * USB_OTG DWC2 HIGH DRIVER CHECK PIPE STATE
400 * parameter1 phost: USBホストハンドラ
401 * parameter2 pipe: PIPE#
402 * return TUSBH_ERCODE
403 */
404bool_t
405dwc2_host_checkpipe(TUSBH_Handle_t *phost, uint8_t pipe)
406{
407 USB_OTG_Handle_t *husb = (USB_OTG_Handle_t *)(phost->pSysData);
408
409 if(pipe < husb->Init.host_channels && husb->hc[pipe].state != USBO_HC_FAIL)
410 return true;
411 else
412 return false;
413}
414
415/*
416 * USB_OTG DWC2 HIGH DRIVER SET PIPE TOGGLE VALUE
417 * parameter1 phost: USBホストハンドラ
418 * parameter2 pipe: PIPE#
419 * parameter3 toggle: トグル値
420 * return TUSBH_ERCODE
421 */
422TUSBH_ERCODE
423dwc2_host_settoggle(TUSBH_Handle_t *phost, uint8_t pipe, uint8_t toggle)
424{
425 USB_OTG_Handle_t *husb = (USB_OTG_Handle_t *)(phost->pSysData);
426
427 if(husb->hc[pipe].ep_is_in){
428 husb->hc[pipe].toggle_in = toggle;
429 }
430 else{
431 husb->hc[pipe].toggle_out = toggle;
432 }
433 return TUSBH_E_OK;
434}
435
436/*
437 * USB_OTG DWC2 HIGH DRIVER GET PIPE TOGGLE VALUE
438 * parameter1 phost: USBホストハンドラ
439 * parameter2 pipe: PIPE#
440 * return トグル値
441 */
442uint8_t
443dwc2_host_gettoggle(TUSBH_Handle_t *phost, uint8_t pipe)
444{
445 USB_OTG_Handle_t *husb = (USB_OTG_Handle_t *)(phost->pSysData);
446 uint8_t toggle = 0;
447
448 if(husb->hc[pipe].ep_is_in){
449 toggle = husb->hc[pipe].toggle_in;
450 }
451 else{
452 toggle = husb->hc[pipe].toggle_out;
453 }
454 return toggle;
455}
456
Note: See TracBrowser for help on using the repository browser.