source: azure_iot_hub_f767zi/trunk/asp_baseplatform/gdic/usb_device/usb_device_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: 13.2 KB
Line 
1/*
2 * TOPPERS BASE PLATFORM MIDDLEWARE
3 *
4 * Copyright (C) 2017-2019 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_device.h"
52
53
54#define sil_orw_mem(a, b) sil_wrw_mem((a), sil_rew_mem(a) | (b))
55#define sil_andw_mem(a, b) sil_wrw_mem((a), sil_rew_mem(a) & ~(b))
56#define sil_orh_mem(a, b) sil_wrh_mem((a), sil_reh_mem(a) | (b))
57#define sil_andh_mem(a, b) sil_wrh_mem((a), sil_reh_mem(a) & ~(b))
58
59#ifndef MAX_DEVICE_EPS
60#define MAX_DEVICE_EPS (MAX_EPS_CHANNELS-1)
61#endif
62
63/*
64 * SETUPSTAGE CALLBACK関数
65 */
66static void
67tusbdSetupStageCallback(USB_DEV_Handle_t *husb)
68{
69 tusbdSetupStage(husb->pDev, (uint8_t *)husb->Setup);
70}
71
72/*
73 * DATAOUTSTAGE CALLBACK関数
74 */
75static void
76tusbdDataOutStageCallback(USB_DEV_Handle_t *husb, uint8_t epnum)
77{
78 tusbdDataOutStage(husb->pDev, epnum, husb->OUT_ep[epnum].xfer_buff);
79}
80
81/*
82 * DATAINSTAGE CALLBACK関数
83 */
84static void
85tusbdDataInStageCallback(USB_DEV_Handle_t *husb, uint8_t epnum)
86{
87 tusbdDataInStage(husb->pDev, epnum, husb->IN_ep[epnum].xfer_buff);
88}
89
90/*
91 * DEVICE RESET CALLBACK関数
92 */
93static void
94tusbdResetCallback(USB_DEV_Handle_t *husb)
95{
96 uint8_t speed = USB_DEVICE_SPEED_FULL;
97
98 /* Set USB Current Speed */
99 switch(husb->Init.speed){
100 case USB_SPEED_HIGH:
101 speed = USB_DEVICE_SPEED_HIGH;
102 break;
103 case USB_SPEED_FULL:
104 speed = USB_DEVICE_SPEED_FULL;
105 break;
106 default:
107 speed = USB_DEVICE_SPEED_FULL;
108 break;
109 }
110
111 /*
112 * DEVICEのリセット
113 */
114 tusbdReset(husb->pDev);
115 tusbdSetSpeed(husb->pDev, speed);
116}
117
118/*
119 * DEVICE SUSPEND CALLBACK関数
120 */
121static void
122tusbdSuspendCallback(USB_DEV_Handle_t *husb)
123{
124 tusbdSuspend(husb->pDev);
125#if 1 /* ROI DEBUG */
126 syslog_0(LOG_NOTICE, "## tusbdSuspendCallback ##");
127#endif
128 /*Enter in STOP mode */
129 if (husb->Init.low_power_enable){
130 /* Set SLEEPDEEP bit and SleepOnExit of Cortex System Control Register */
131 sil_orw_mem((uint32_t *)(TADR_SCB_BASE+TOFF_SCB_SCR), (SCB_SCR_SLEEPDEEP_Msk | SCB_SCR_SLEEPONEXIT_Msk));
132 }
133}
134
135/*
136 * DEVICE RESUME CALLBACK関数
137 */
138static void
139tusbdResumeCallback(USB_DEV_Handle_t *husb)
140{
141 TUSBD_Handle_t *pdevice = husb->pDev;
142 if(husb->Init.low_power_enable && pdevice->dev_state == TUSBD_STATE_SUSPENDED){
143 /* Reset SLEEPDEEP bit of Cortex System Control Register */
144 sil_andw_mem((uint32_t *)(TADR_SCB_BASE+TOFF_SCB_SCR), (SCB_SCR_SLEEPDEEP_Msk | SCB_SCR_SLEEPONEXIT_Msk));
145 sysclock_config(1);
146 }
147 tusbdResume(husb->pDev);
148#if 1 /* ROI DEBUG */
149 syslog_0(LOG_NOTICE, "## tusbdResumeCallback ##");
150#endif
151}
152
153/*
154 * DEVICE CONNECT CALLBACK関数
155 */
156static void
157tusbdConnectCallback(USB_DEV_Handle_t *husb)
158{
159 tusbdDeviceConnected(husb->pDev);
160}
161
162/*
163 * DEVICE DISCONNECT CALLBACK関数
164 */
165static void
166tusbdDisconnectCallback(USB_DEV_Handle_t *husb)
167{
168 tusbdDeviceDisconnected(husb->pDev);
169}
170
171/*
172 * ENDPOINT取得
173 */
174static USB_DEV_EPTypeDef *
175tusbdGetEndpoint(USB_DEV_Handle_t *husb, uint8_t addr)
176{
177 USB_DEV_EPTypeDef *ep;
178
179 if((addr & USB_DEVICE_TO_HOST) != 0){
180 ep = &husb->IN_ep[addr & 0x7F];
181 }
182 else{
183 ep = &husb->OUT_ep[addr & 0x7F];
184 }
185 ep->num = addr & 0x7F;
186 ep->is_in = (USB_DEVICE_TO_HOST & addr) != 0;
187 return ep;
188}
189
190
191/*
192 * USB_DEVICE HIGH DRIVER INITIALIZE
193 * parameter1 pdevice: USBデバイスハンドラ
194 * return TUSBD_ERCODE
195 */
196TUSBD_ERCODE
197usb_device_init(TUSBD_Handle_t *pdevice)
198{
199 USB_DEV_Handle_t *husb = (USB_DEV_Handle_t *)(pdevice->pSysData);
200 uint32_t i = 0;
201
202 /*
203 * USBハンドラに、USBデバイスハンドラをセット
204 */
205 husb->pDev = pdevice;
206
207 /*
208 * コールバック関数をセット
209 */
210 husb->devsetupstagecallback = tusbdSetupStageCallback;
211 husb->devdataoutstagecallback = tusbdDataOutStageCallback;
212 husb->devdatainstagecallback = tusbdDataInStageCallback;
213 husb->devsofcallback = NULL;
214 husb->devresetcallback = tusbdResetCallback;
215 husb->devsuspendcallback = tusbdSuspendCallback;
216 husb->devresumecallback = tusbdResumeCallback;
217 husb->devconnectcallback = tusbdConnectCallback;
218 husb->devdisconnectcallback = tusbdDisconnectCallback;
219 husb->devlpmcallback = NULL;
220
221 /*
222 * エンドポイントの初期化
223 */
224 for(i = 0 ; i < MAX_DEVICE_EPS ; i++){
225 husb->IN_ep[i].is_in = 1;
226 husb->IN_ep[i].num = i;
227 husb->IN_ep[i].type = EP_TYPE_CTRL;
228 husb->IN_ep[i].maxpacket = 0;
229 husb->IN_ep[i].xfer_buff = 0;
230 husb->IN_ep[i].xfer_len = 0;
231
232 husb->OUT_ep[i].is_in = 0;
233 husb->OUT_ep[i].num = i;
234 husb->OUT_ep[i].type = EP_TYPE_CTRL;
235 husb->OUT_ep[i].maxpacket = 0;
236 husb->OUT_ep[i].xfer_buff = 0;
237 husb->OUT_ep[i].xfer_len = 0;
238 }
239
240 /*
241 * LPMの有効化
242 */
243 usbd_init_lpm(husb);
244 usbd_init_BCD(husb);
245
246 usbd_setupPMA(husb , 0x00 , PCD_SNG_BUF, 0x18);
247 usbd_setupPMA(husb , 0x80 , PCD_SNG_BUF, 0x58);
248 usbd_setupPMA(husb , 0x81 , PCD_SNG_BUF, 0x98);
249 usbd_setupPMA(husb , 0x82 , PCD_SNG_BUF, 0xD8);
250 return TUSBD_E_OK;
251}
252
253/*
254 * USB_DEVICE HIGH DRIVER DE-INITIALIZE
255 * parameter1 pdevice: USBデバイスハンドラ
256 * return TUSBD_ERCODE
257 */
258TUSBD_ERCODE
259usb_device_deinit(TUSBD_Handle_t *pdevice)
260{
261 /*
262 * デバイス停止
263 */
264 usb_device_stop(pdevice);
265
266 /*
267 * デバイスハードウェア終了
268 */
269 usbd_deinit(pdevice->pSysData);
270 return TUSBD_E_OK;
271}
272
273/*
274 * USB DEVICE HIGH DRIVER START
275 * parameter1 pdevice: USBデバイスハンドラ
276 * return TUSBD_ERCODE
277 */
278TUSBD_ERCODE
279usb_device_start(TUSBD_Handle_t *pdevice)
280{
281 usbd_devconnect(pdevice->pSysData);
282 return TUSBD_E_OK;
283}
284
285/*
286 * USB DEVICE HIGH DRIVER STOP
287 * parameter1 pdevice: USBデバイスハンドラ
288 * return TUSBD_ERCODE
289 */
290TUSBD_ERCODE
291usb_device_stop(TUSBD_Handle_t *pdevice)
292{
293 usbd_devdisconnect(pdevice->pSysData);
294 return TUSBD_E_OK;
295}
296
297/*
298 * USB DEVICE HIGH DRIVER OPEN ENDPOINT
299 * parameter1 pdevice: USBデバイスハンドラ
300 * parameter2 addr: endpointアドレス
301 * parameter3 type: endpointタイプ
302 * parameter4 mps: MAX PACKET SIZE
303 * return TUSBD_ERCODE
304 */
305TUSBD_ERCODE
306usb_device_openep(TUSBD_Handle_t *pdevice, uint8_t addr, uint8_t type, uint16_t mps)
307{
308 USB_DEV_Handle_t *husb = pdevice->pSysData;
309 USB_DEV_EPTypeDef *ep;
310
311 ep = tusbdGetEndpoint(husb, addr);
312 ep->maxpacket = mps;
313 ep->type = type;
314 usbd_activateEndpoint(husb, ep);
315 return TUSBD_E_OK;
316}
317
318/*
319 * USB DEVICE HIGH DRIVER CLOSE ENDPOINT
320 * parameter1 pdevice: USBデバイスハンドラ
321 * parameter2 addr: endpointアドレス
322 * return TUSBD_ERCODE
323 */
324TUSBD_ERCODE
325usb_device_closeep(TUSBD_Handle_t *pdevice, uint8_t addr)
326{
327 USB_DEV_Handle_t *husb = pdevice->pSysData;
328 USB_DEV_EPTypeDef *ep;
329
330 ep = tusbdGetEndpoint(husb, addr);
331 usbd_deactivateEndpoint(husb, ep);
332 return TUSBD_E_OK;
333}
334
335/*
336 * USB DEVICE HIGH DRIVER FLUSH ENDPOINT
337 * parameter1 pdevice: USBデバイスハンドラ
338 * parameter2 addr: endpointアドレス
339 * return TUSBD_ERCODE
340 */
341TUSBD_ERCODE
342usb_device_flushep(TUSBD_Handle_t *pdevice, uint8_t addr)
343{
344 return TUSBD_E_OK;
345}
346
347/*
348 * USB DEVICE HIGH DRIVER STALL ENDPOINT
349 * parameter1 pdevice: USBデバイスハンドラ
350 * parameter2 addr: endpointアドレス
351 * return TUSBD_ERCODE
352 */
353TUSBD_ERCODE
354usb_device_stallep(TUSBD_Handle_t *pdevice, uint8_t addr)
355{
356 USB_DEV_Handle_t *husb = pdevice->pSysData;
357 USB_DEV_EPTypeDef *ep;
358
359 ep = tusbdGetEndpoint(husb, addr);
360 ep->is_stall = 1;
361
362 usbd_epsetStall(husb, ep);
363 return TUSBD_E_OK;
364}
365
366/*
367 * USB DEVICE HIGH DRIVER CLEAR STALL-ENDPOINT
368 * parameter1 pdevice: USBデバイスハンドラ
369 * parameter2 addr: endpointアドレス
370 * return TUSBD_ERCODE
371 */
372TUSBD_ERCODE
373usb_device_clearep(TUSBD_Handle_t *pdevice, uint8_t addr)
374{
375 USB_DEV_Handle_t *husb = pdevice->pSysData;
376 USB_DEV_EPTypeDef *ep;
377
378 ep = tusbdGetEndpoint(husb, addr);
379 ep->is_stall = 0;
380
381 usbd_epclearStall(husb, ep);
382 return TUSBD_E_OK;
383}
384
385/*
386 * USB DEVICE HIGH DRIVER GET STALL CONDITION
387 * parameter1 pdevice: USBデバイスハンドラ
388 * parameter2 addr: endpointアドレス
389 * return 1:stall 0:not stall
390 */
391uint8_t
392usb_device_getstallcondition(TUSBD_Handle_t *pdevice, uint8_t addr)
393{
394 USB_DEV_Handle_t *husb = pdevice->pSysData;
395
396 if((addr & USB_DEVICE_TO_HOST) != 0)
397 return husb->IN_ep[addr & 0x7F].is_stall;
398 else
399 return husb->OUT_ep[addr & 0x7F].is_stall;
400}
401
402/*
403 * USB DEVICE HIGH DRIVER TRANSMIT A DATA
404 * parameter1 pdevice: USBデバイスハンドラ
405 * parameter2 addr: endpointアドレス
406 * parameter3 pbuf: 送信データバッファ
407 * parameter4 size: 送信サイズ
408 * return TUSBD_ERCODE
409 */
410TUSBD_ERCODE
411usb_device_transmitdata(TUSBD_Handle_t *pdevice, uint8_t addr, uint8_t *pbuf, uint16_t size)
412{
413 USB_DEV_Handle_t *husb = pdevice->pSysData;
414 USB_DEV_EPTypeDef *ep;
415
416 ep = tusbdGetEndpoint(husb, (addr | USB_DEVICE_TO_HOST));
417
418 /*
419 * 送信データ設定
420 */
421 ep->xfer_buff = pbuf;
422 ep->xfer_len = size;
423 ep->xfer_count = 0;
424 usbd_epstartsend(husb, ep);
425 return TUSBD_E_OK;
426}
427
428/*
429 * USB DEVICE HIGH DRIVER START to RECEIVE
430 * parameter1 pdevice: USBデバイスハンドラ
431 * parameter2 addr: endpointアドレス
432 * parameter3 pbuf: 受信データバッファ
433 * parameter4 size: 受信サイズ
434 * return TUSBD_ERCODE
435 */
436TUSBD_ERCODE
437usb_device_startreceive(TUSBD_Handle_t *pdevice, uint8_t addr, uint8_t *pbuf, uint16_t size)
438{
439 USB_DEV_Handle_t *husb = pdevice->pSysData;
440 USB_DEV_EPTypeDef *ep;
441
442 ep = tusbdGetEndpoint(husb, (addr & ~USB_DEVICE_TO_HOST));
443
444 /*
445 * 受信データ設定
446 */
447 ep->xfer_buff = pbuf;
448 ep->xfer_len = size;
449 ep->xfer_count = 0;
450 usbd_epstartreceive(husb, ep);
451 return TUSBD_E_OK;
452}
453
454/*
455 * USB DEVICE HIGH DRIVER TEST MODE
456 * parameter1 pdevice: USBデバイスハンドラ
457 * return TUSBD_ERCODE
458 */
459TUSBD_ERCODE
460usb_device_testmode(TUSBD_Handle_t *pdevice)
461{
462 return TUSBD_E_OK;
463}
464
465/*
466 * USB DEVICE HIGH DRIVER REMOTE WAKEUP
467 * parameter1 pdevice: USBデバイスハンドラ
468 * return TUSBD_ERCODE
469 */
470void
471usb_device_wakeup(USBD_HandleTypeDef *pdevice)
472{
473 USB_DEV_Handle_t *husb = pdevice->pSysData;
474
475 if(pdevice->dev_remote_wakeup == 1 && pdevice->dev_state == TUSBD_STATE_SUSPENDED){
476 if(husb->Init.low_power_enable){
477 /* Reset SLEEPDEEP bit of Cortex System Control Register */
478 sil_andw_mem((uint32_t *)(TADR_SCB_BASE+TOFF_SCB_SCR), (SCB_SCR_SLEEPDEEP_Msk | SCB_SCR_SLEEPONEXIT_Msk));
479 sysclock_config(1);
480 }
481 /* Activate Remote wakeup */
482 if(husb->Init.lpm_enable == 1) /* Apply L1 Resume */
483 sil_orh_mem((uint16_t *)(husb->base+TOFF_USB_CNTR), USB_CNTR_L1RESUME);
484 else /* Apply L2 Resume */
485 sil_orh_mem((uint16_t *)(husb->base+TOFF_USB_CNTR), USB_CNTR_RESUME);
486
487 /* Remote wakeup delay */
488 sil_dly_nse(10*1000*1000);
489
490 if(husb->Init.lpm_enable == 1) /* Release L1 Resume */
491 sil_andh_mem((uint16_t *)(husb->base+TOFF_USB_CNTR), USB_CNTR_L1RESUME);
492 else /* Release L2 Resume */
493 sil_andh_mem((uint16_t *)(husb->base+TOFF_USB_CNTR), USB_CNTR_RESUME);
494 /* Change remote_wakeup feature to 0*/
495 pdevice->dev_remote_wakeup = 0;
496 }
497}
498
Note: See TracBrowser for help on using the repository browser.