source: azure_iot_hub_f767zi/trunk/asp_baseplatform/pdic/stm32f7xx/usb_otg.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: 90.1 KB
Line 
1/*
2 * TOPPERS/ASP Kernel
3 * Toyohashi Open Platform for Embedded Real-Time Systems/
4 * Advanced Standard Profile Kernel
5 *
6 * Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
7 * Toyohashi Univ. of Technology, JAPAN
8 * Copyright (C) 2015-2019 by TOPPERS PROJECT Educational Working Group.
9 *
10 * 上記著作権者は,以下の(1)~(4)の条件を満たす場合に限り,本ソフトウェ
11 * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
12 * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
13 * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
14 * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
15 * スコード中に含まれていること.
16 * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
17 * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
18 * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
19 * の無保証規定を掲載すること.
20 * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
21 * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
22 * と.
23 * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
24 * 作権表示,この利用条件および下記の無保証規定を掲載すること.
25 * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
26 * 報告すること.
27 * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
28 * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
29 * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
30 * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
31 * 免責すること.
32 *
33 * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
34 * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
35 * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
36 * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
37 * の責任を負わない.
38 *
39 * $Id$
40 */
41
42/*
43 * USB_OTGドライバの本体
44 */
45
46#include "kernel_impl.h"
47#include <t_syslog.h>
48#include <t_stdlib.h>
49#include <string.h>
50#include <sil.h>
51#include "syssvc/serial.h"
52#include "syssvc/syslog.h"
53#include "kernel_cfg.h"
54#include <target_syssvc.h>
55#include "device.h"
56#include "usb_otg.h"
57
58#define sil_orw_mem(a, b) sil_wrw_mem((a), sil_rew_mem(a) | (b))
59#define sil_andw_mem(a, b) sil_wrw_mem((a), sil_rew_mem(a) & ~(b))
60#define sil_andxw_mem(a, b) sil_wrw_mem((a), sil_rew_mem(a) & (b))
61#define sil_modw_mem(a, b, c) sil_wrw_mem((a), (sil_rew_mem(a) & (~b)) | (c))
62
63#define get_usbmode(a) (sil_rew_mem((uint32_t *)(USBOTG_BASE((a))+TOFF_USBO_GINTSTS)) & 1)
64#define get_int_status(a, b) (sil_rew_mem((uint32_t *)(USBOTG_BASE((a))+TOFF_USBO_GINTSTS)) & (b))
65#define hc_int_status(a, b, c) (sil_rew_mem((uint32_t *)(USBHC_BASE((a), (b))+TOFF_USBHC_HCINT)) & (c))
66#define get_haint_status(a) (sil_rew_mem((uint32_t *)(USBH_BASE((a))+TOFF_USBH_HAINT)) & 0xFFFF)
67#define clear_host_int(a, b) sil_wrw_mem((uint32_t *)(USBOTG_BASE((a))+TOFF_USBO_GINTSTS), (b))
68#define clear_dev_int(a, b) sil_andxw_mem((uint32_t *)(USBOTG_BASE((a))+TOFF_USBO_GINTSTS), (b))
69#define clear_hc_int(a, b, c) sil_wrw_mem((uint32_t *)(USBHC_BASE((a), (b))+TOFF_USBHC_HCINT), (c))
70#define clear_outep_int(a, b, c) sil_wrw_mem((uint32_t *)(USBOEP_BASE((a), (b))+TOFF_USBEO_DOEPINT), (c))
71#define clear_inep_int(a, b, c) sil_wrw_mem((uint32_t *)(USBIEP_BASE((a), (b))+TOFF_USBEI_DIEPINT), (c))
72#define get_inep_int_status(a) ((sil_rew_mem((uint32_t *)(USBD_BASE((a))+TOFF_USBD_DAINT)) \
73 & sil_rew_mem((uint32_t *)(USBD_BASE((a))+TOFF_USBD_DAINTMSK))) & 0xFFFF)
74#define get_outep_int_status(a) (((sil_rew_mem((uint32_t *)(USBD_BASE((a))+TOFF_USBD_DAINT)) \
75 & sil_rew_mem((uint32_t *)(USBD_BASE((a))+TOFF_USBD_DAINTMSK))) & 0xFFFF0000) >> 16)
76
77#define get_packet_data(s) ((s[0] & 0xff) | ((s[1] & 0xff)<<8) | ((s[2] & 0xff)<<16) | ((s[3] & 0xff)<<24))
78
79/*
80 * USB用 AF10定義
81 */
82#define GPIO_AF10_OTG_FS ((uint8_t)0x0AU) /* OTG_FS Alternate Function mapping */
83#define GPIO_AF10_OTG_HS ((uint8_t)0x0AU) /* OTG_HS Alternate Function mapping */
84
85/*
86 * デフォルトFIFO設定
87 */
88#define DEFAULT_FS_GRXFSIZ 0x80
89#define DEFAULT_HS_GRXFSIZ 0x200
90#define DEFAULT_FS_TXFIFO0_SIZ 0x60 /* 0x40 */
91#define DEFAULT_HS_TXFIFO0_SIZ 0x100
92#define DEFAULT_FS_TXFIFO1_SIZ 0x80 /* 0x40 */
93#define DEFAULT_HS_TXFIFO1_SIZ 0xE0
94
95
96/*
97 * パケットサイズ定義
98 */
99#define USB_OTG_HS_MAX_PACKET_SIZE 512
100#define USB_OTG_FS_MAX_PACKET_SIZE 64
101#define USB_OTG_MAX_EP0_SIZE 64
102
103/*
104 * PHY周波数定義
105 */
106#define DSTS_ENUMSPD_HS_PHY_30MHZ_OR_60MHZ (0 << 1)
107#define DSTS_ENUMSPD_FS_PHY_30MHZ_OR_60MHZ (1 << 1)
108#define DSTS_ENUMSPD_LS_PHY_6MHZ (2 << 1)
109#define DSTS_ENUMSPD_FS_PHY_48MHZ (3 << 1)
110
111/*
112 * フレームインターバル定義
113 */
114#define DCFG_FRAME_INTERVAL_80 0
115#define DCFG_FRAME_INTERVAL_85 1
116#define DCFG_FRAME_INTERVAL_90 2
117#define DCFG_FRAME_INTERVAL_95 3
118
119/*
120 * パケットステータス定義
121 */
122#define STS_GOUT_NAK 1
123#define STS_DATA_UPDT 2
124#define STS_XFER_COMP 3
125#define STS_SETUP_COMP 4
126#define STS_SETUP_UPDT 6
127
128/*
129 * PHYスピード定義
130 */
131#define HPRT0_PRTSPD_HIGH_SPEED 0
132#define HPRT0_PRTSPD_FULL_SPEED 1
133#define HPRT0_PRTSPD_LOW_SPEED 2
134
135/*
136 * ホストクラスエンドポイントタイプ定義
137 */
138#define HCCHAR_CTRL 0
139#define HCCHAR_ISOC 1
140#define HCCHAR_BULK 2
141#define HCCHAR_INTR 3
142
143
144#define GRXSTS_PKTSTS_IN 2
145#define GRXSTS_PKTSTS_IN_XFER_COMP 3
146#define GRXSTS_PKTSTS_DATA_TOGGLE_ERR 5
147#define GRXSTS_PKTSTS_CH_HALTED 7
148
149#define RESET_TIMEOUT (1000*100) /* 1ms */
150#define HALT_TIMEOUT (10*100) /* 0.01ms */
151#ifndef USB_OTG_FS_WAKEUP_EXTI_LINE
152#define USB_OTG_FS_WAKEUP_EXTI_LINE 0x00040000 /* External interrupt line 18 Connected to the USB FS EXTI Line */
153#endif
154
155#define GHWCFG3_XFER_SIZE_CNTR_WIDTH 0x0000000f
156#define GHWCFG3_PACKET_SIZE_CNTR_WIDTH 0x00000070
157#define GHWCFG3_I2C 0x00000100
158#define GHWCFG3_DFIFO_DEPTH 0xffff0000
159#define GRXFSIZ_DEPTH 0x0000ffff
160
161/*
162 * USBポートIDから管理ブロックを取り出すためのマクロ
163 */
164#define INDEX_USB(usbid) ((uint_t)((usbid) - 1))
165
166#ifndef TADR_USB_OTGHS_BASE
167#define NUM_USBHANDLE 1
168#else
169#define NUM_USBHANDLE NUM_USBPORT
170#endif
171
172#if !defined(_STM32F7XX_H_)
173#define flushinvalidatedcache_by_addr(a, b)
174#endif
175
176static USB_OTG_Handle_t Husb[NUM_USBPORT];
177
178extern ER sysclock_config(int mode);
179
180/*
181 * 必要なら強制モードを設定する
182 * 強制モードならtrueを返す
183 */
184static bool_t
185usbo_force_mode_if_needed(USB_OTG_Handle_t *husb, bool_t host)
186{
187 uint32_t otgmode = get_usbmode(husb->base);
188 uint32_t reqmode = husb->Init.usb_otg_mode;
189 uint32_t gusbcfg;
190 uint32_t set, clear;
191
192 if (host && (otgmode == USB_OTG_MODE_HOST || reqmode == USB_OTG_MODE_DEVICE))
193 return false;
194 else if (!host && (otgmode == USB_OTG_MODE_DEVICE || reqmode == USB_OTG_MODE_HOST))
195 return false;
196
197 gusbcfg = sil_rew_mem((uint32_t *)(USBOTG_BASE(husb->base)+TOFF_USBO_GUSBCFG));
198 set = host ? USB_OTG_GUSBCFG_FHMOD : USB_OTG_GUSBCFG_FDMOD;
199 clear = host ? USB_OTG_GUSBCFG_FDMOD : USB_OTG_GUSBCFG_FHMOD;
200 gusbcfg &= ~clear;
201 gusbcfg |= set;
202 sil_wrw_mem((uint32_t *)(USBOTG_BASE(husb->base)+TOFF_USBO_GUSBCFG), gusbcfg);
203
204 dly_tsk(25);
205 return true;
206}
207
208/*
209 * 強制モードをクリアする
210 */
211static void
212usbo_clear_force_mode(USB_OTG_Handle_t *husb)
213{
214 uint32_t gusbcfg;
215
216 gusbcfg = sil_rew_mem((uint32_t *)(USBOTG_BASE(husb->base)+TOFF_USBO_GUSBCFG));
217 gusbcfg &= ~USB_OTG_GUSBCFG_FHMOD;
218 gusbcfg &= ~USB_OTG_GUSBCFG_FDMOD;
219 sil_wrw_mem((uint32_t *)(USBOTG_BASE(husb->base)+TOFF_USBO_GUSBCFG), gusbcfg);
220
221 /*
222 * 設定変更による待ち
223 */
224 dly_tsk(25);
225}
226
227/*
228 * USB-OTGモードチェック
229 */
230static void
231usbo_get_hwparam(USB_OTG_Handle_t *husb)
232{
233 USB_OTG_HwParam_t *hw = &husb->hw_params;
234 uint32_t hwcfg3, grxfsiz;
235 unsigned int width;
236
237#ifdef TOFF_USBO_GHWCFG3
238 hwcfg3 = sil_rew_mem((uint32_t *)(husb->base+TOFF_USBO_GHWCFG3));
239#else
240 hwcfg3 = 0x200d1e8;
241#endif
242 grxfsiz = sil_rew_mem((uint32_t *)(husb->base+TOFF_USBO_GRXFSIZ));
243 syslog_2(LOG_NOTICE, "hwcfg3=%08x grxfsiz=%08x", hwcfg3, grxfsiz);
244
245 hw->en_multiple_tx_fifo = 0;
246 width = hwcfg3 & GHWCFG3_XFER_SIZE_CNTR_WIDTH;
247 hw->max_transfer_size = (1 << (width + 11)) - 1;
248 width = (hwcfg3 & GHWCFG3_PACKET_SIZE_CNTR_WIDTH) >> 4;
249 hw->max_packet_count = (1 << (width + 4)) - 1;
250 hw->total_fifo_size = (hwcfg3 & GHWCFG3_DFIFO_DEPTH) >> 16;
251 hw->host_rx_fifo_size = grxfsiz & GRXFSIZ_DEPTH;
252
253 syslog_1(LOG_NOTICE, " max_transfer_size=%d", hw->max_transfer_size);
254 syslog_1(LOG_NOTICE, " max_packet_count=%d", hw->max_packet_count);
255 syslog_1(LOG_NOTICE, " en_multiple_tx_fifo=%d", hw->en_multiple_tx_fifo);
256 syslog_1(LOG_NOTICE, " total_fifo_size=%d", hw->total_fifo_size);
257 syslog_1(LOG_NOTICE, " host_rx_fifo_size=%d", hw->host_rx_fifo_size);
258}
259
260/*
261 * USB OTG 省エネモード復帰
262 */
263static ER
264usbo_exit_hibernation(USB_OTG_Handle_t *husb, bool_t restore)
265{
266 /*
267 * リモートウェークアップシグナルクリア
268 */
269 sil_andw_mem((uint32_t *)(USBD_BASE(husb->base)+TOFF_USBD_DCTL), USB_OTG_DCTL_RWUSIG);
270 return E_OK;
271}
272
273/*
274 * USB OTG 省エネモード移行
275 */
276static ER
277usbo_enter_hibernation(USB_OTG_Handle_t *husb)
278{
279 sil_orw_mem((uint32_t *)(USBPGC_BASE(husb->base)), USB_OTG_PCGCCTL_STOPCLK);
280 /*Enter in STOP mode */
281 if(husb->Init.low_power_enable){
282 /* Set SLEEPDEEP bit and SleepOnExit of Cortex System Control Register */
283 sil_orw_mem((uint32_t *)(TADR_SCB_BASE+TOFF_SCB_SCR), (SCB_SCR_SLEEPDEEP_Msk | SCB_SCR_SLEEPONEXIT_Msk));
284 }
285 return E_OK;
286}
287
288/*
289 * USB_OTGハードウェア初期化
290 * parameter1 portid USBポートID
291 * parameter2 pini 初期化構造体へのポインタ
292 * return NULLでなければUSBハンドラへのポインタ
293 */
294USB_OTG_Handle_t *
295usbo_init(ID portid, USB_OTG_Init_t *pini)
296{
297 GPIO_Init_t GPIO_Init_Data;
298 USB_OTG_Handle_t *husb;
299 uint32_t base;
300 uint32_t no;
301 volatile uint32_t tmpreg = 0x00U;
302
303 if(portid < USB1_PORTID || portid > NUM_USBHANDLE)
304 return NULL;
305
306 no = INDEX_USB(portid);
307 husb = &Husb[no];
308 memcpy(&husb->Init, pini, sizeof(USB_OTG_Init_t));
309
310 if(portid == USB1_PORTID){ /* USB OTG FSポート */
311 husb->base = TADR_USB_OTGFS_BASE;
312 /*
313 * GPIO/USBポートクロック起動
314 */
315 sil_orw_mem((uint32_t *)ENABLE_FS_BASE1, ENABLE_FS_VAL1);
316#if defined(ENABLE_FS_BASE2)
317 sil_orw_mem((uint32_t *)ENABLE_FS_BASE2, ENABLE_FS_VAL2);
318#endif
319
320 /*USB DM and DP */
321 GPIO_Init_Data.mode = GPIO_MODE_AF;
322 GPIO_Init_Data.pull = GPIO_NOPULL;
323 GPIO_Init_Data.otype = GPIO_OTYPE_PP;
324 GPIO_Init_Data.speed = GPIO_SPEED_HIGH;
325 GPIO_Init_Data.alternate = GPIO_AF10_OTG_FS;
326 gpio_setup(TADR_FS_G1_BASE, &GPIO_Init_Data, FS_DM_PINNO);
327 gpio_setup(TADR_FS_G1_BASE, &GPIO_Init_Data, FS_DP_PINNO);
328
329#if defined(FS_ID_PINNO)
330 /*USB ID */
331 GPIO_Init_Data.mode = GPIO_MODE_AF;
332 GPIO_Init_Data.pull = GPIO_PULLUP;
333 GPIO_Init_Data.otype = GPIO_OTYPE_OD;
334 GPIO_Init_Data.speed = GPIO_SPEED_HIGH;
335 GPIO_Init_Data.alternate = GPIO_AF10_OTG_FS;
336 gpio_setup(TADR_FS_G1_BASE, &GPIO_Init_Data, FS_ID_PINNO);
337#endif
338
339#if defined(FS_VBUS_PINNO)
340 /* Configure VBUS Pin(DEVICE) */
341 GPIO_Init_Data.mode = GPIO_MODE_INPUT;
342 GPIO_Init_Data.pull = GPIO_NOPULL;
343 GPIO_Init_Data.otype = GPIO_OTYPE_PP;
344 gpio_setup(TADR_FS_G1_BASE, &GPIO_Init_Data, FS_VBUS_PINNO);
345#endif
346
347#if defined(FS_POWERSW_PINO)
348 /* Configure POWER_SWITCH IO pin(HOST) */
349 GPIO_Init_Data.mode = GPIO_MODE_OUTPUT;
350 GPIO_Init_Data.pull = GPIO_NOPULL;
351#ifdef FS_G2_PORT_TYPE
352 GPIO_Init_Data.otype = FS_G2_PORT_TYPE;
353#else
354 GPIO_Init_Data.otype = GPIO_OTYPE_PP;
355#endif
356 GPIO_Init_Data.speed = GPIO_SPEED_HIGH;
357 gpio_setup(TADR_FS_G2_BASE, &GPIO_Init_Data, FS_POWERSW_PINO);
358#endif
359
360 /*
361 * USB FSクロック設定
362 */
363 sil_orw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_USBFS), RCC_USBFSEN);
364 sil_orw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_SYSFG), RCC_SYSGFGEN);
365 tmpreg = sil_rew_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_SYSFG));
366
367 /*
368 * FIFO設定値
369 */
370 usbo_get_hwparam(husb);
371 husb->fifo_mem = husb->hw_params.total_fifo_size;
372 husb->pcd_rx_fifo_sz = DEFAULT_FS_GRXFSIZ;
373 husb->pcd_np_g_tx_fifo_sz = DEFAULT_FS_TXFIFO0_SIZ;
374 husb->pcd_tx_fifo_sz[1] = DEFAULT_FS_TXFIFO1_SIZ;
375 }
376#ifdef TADR_USB_OTGHS_BASE
377 else{ /* USB OTG HSポート */
378 husb->base = TADR_USB_OTGHS_BASE;
379 /*
380 * GPIO/USBポートクロック起動
381 */
382 sil_orw_mem((uint32_t *)ENABLE_HS_BASE, ENABLE_HS_VAL2);
383 sil_orw_mem((uint32_t *)ENABLE_HS_BASE, ENABLE_HS_VAL3);
384#if defined(TOPPERS_STM32F723_DISCOVERY)
385
386 /*USB DM and DP */
387 GPIO_Init_Data.mode = GPIO_MODE_AF;
388 GPIO_Init_Data.pull = GPIO_NOPULL;
389 GPIO_Init_Data.otype = GPIO_OTYPE_PP;
390 GPIO_Init_Data.speed = GPIO_SPEED_HIGH;
391 GPIO_Init_Data.alternate = GPIO_AF10_OTG_HS;
392 gpio_setup(TADR_GPIOB_BASE, &GPIO_Init_Data, 14);
393 gpio_setup(TADR_GPIOB_BASE, &GPIO_Init_Data, 15);
394
395 /* Configure POWER_SWITCH IO pin(HOST) */
396 GPIO_Init_Data.mode = GPIO_MODE_OUTPUT;
397 GPIO_Init_Data.pull = GPIO_NOPULL;
398 GPIO_Init_Data.speed = GPIO_SPEED_HIGH;
399 GPIO_Init_Data.otype = GPIO_OTYPE_PP;
400 gpio_setup(TADR_GPIOH_BASE, &GPIO_Init_Data, 12);
401
402
403 /*
404 * USB HS-PHYクロック設定
405 */
406 sil_orw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_AHB1ENR), RCC_AHB1ENR_OTGHSULPIEN);
407 tmpreg = sil_rew_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_AHB1ENR));
408
409 sil_orw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_AHB1ENR), RCC_AHB1ENR_OTGHSULPIEN);
410 tmpreg = sil_rew_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_AHB1ENR));
411
412#else /* !TOPPERS_STM32F723_DISCOVERY */
413 sil_orw_mem((uint32_t *)ENABLE_HS_BASE, ENABLE_HS_VAL4);
414 sil_orw_mem((uint32_t *)ENABLE_HS_BASE, ENABLE_HS_VAL5);
415 sil_orw_mem((uint32_t *)ENABLE_HS_BASE, ENABLE_HS_VAL1);
416
417 /* CLK */
418 GPIO_Init_Data.mode = GPIO_MODE_AF;
419 GPIO_Init_Data.pull = GPIO_NOPULL;
420 GPIO_Init_Data.otype = GPIO_OTYPE_PP;
421 GPIO_Init_Data.speed = GPIO_SPEED_HIGH;
422 GPIO_Init_Data.alternate = GPIO_AF10_OTG_HS;
423 gpio_setup(TADR_GPIOA_BASE, &GPIO_Init_Data, 5);
424
425 /* D0 */
426 gpio_setup(TADR_GPIOA_BASE, &GPIO_Init_Data, 3);
427
428 /* D1 D2 D3 D4 D5 D6 D7 */
429 gpio_setup(TADR_GPIOB_BASE, &GPIO_Init_Data, 0);
430 gpio_setup(TADR_GPIOB_BASE, &GPIO_Init_Data, 1);
431 gpio_setup(TADR_GPIOB_BASE, &GPIO_Init_Data, 5);
432 gpio_setup(TADR_GPIOB_BASE, &GPIO_Init_Data, 10);
433 gpio_setup(TADR_GPIOB_BASE, &GPIO_Init_Data, 11);
434 gpio_setup(TADR_GPIOB_BASE, &GPIO_Init_Data, 12);
435 gpio_setup(TADR_GPIOB_BASE, &GPIO_Init_Data, 13);
436
437 /* STP */
438 gpio_setup(TADR_GPIOC_BASE, &GPIO_Init_Data, 0);
439
440 /* NXT */
441 gpio_setup(TADR_GPIOH_BASE, &GPIO_Init_Data, 4);
442
443 /* DIR */
444 gpio_setup(TADR_HS_G1_BASE, &GPIO_Init_Data, HS_DIR_PINNNO);
445
446 /*
447 * USB HS-PHYクロック設定
448 */
449 sil_orw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_USBHS), RCC_USBHSUPEN);
450 tmpreg = sil_rew_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_USBHS));
451#endif /* !TOPPERS_STM32F723_DISCOVERY */
452
453 /*
454 * USB HSクロック設定
455 */
456 sil_orw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_USBHS), RCC_USBHSEN);
457 tmpreg = sil_rew_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_USBHS));
458
459 /*
460 * FIFO設定値
461 */
462 usbo_get_hwparam(husb);
463 husb->fifo_mem = husb->hw_params.total_fifo_size;
464 husb->pcd_rx_fifo_sz = DEFAULT_HS_GRXFSIZ;
465 husb->pcd_np_g_tx_fifo_sz = DEFAULT_HS_TXFIFO0_SIZ;
466 husb->pcd_tx_fifo_sz[1] = DEFAULT_HS_TXFIFO1_SIZ;
467 }
468#endif
469 ((void)(tmpreg));
470
471 /* DEVICE */
472 if(husb->Init.low_power_enable == 1){
473 /*
474 * WAKEUP割込み設定
475 */
476#ifdef EXTI_PR_BASE
477 sil_wrw_mem((uint32_t *)EXTI_PR_BASE, USB_OTG_FS_WAKEUP_EXTI_LINE);
478 sil_andw_mem((uint32_t *)(TADR_EXTI_BASE+TOFF_EXTI_FTSR), USB_OTG_FS_WAKEUP_EXTI_LINE);
479 sil_orw_mem((uint32_t *)(TADR_EXTI_BASE+TOFF_EXTI_RTSR), USB_OTG_FS_WAKEUP_EXTI_LINE);
480#endif
481 sil_orw_mem((uint32_t *)EXTI_IMR_BASE, USB_OTG_FS_WAKEUP_EXTI_LINE);
482 }
483
484 base = husb->base;
485 /*
486 * USB OTGグローバル割込み禁止
487 */
488 usbo_disableglobalint(husb);
489
490 /*
491 * USB OTGコア部初期化
492 */
493 usbo_coreinit(husb);
494
495 /*
496 * USB OTGモード設定
497 */
498 usbo_setcurrentmode(husb);
499
500 /*
501 * VBUS Sensing Bを有効設定
502 */
503#ifdef USB_OTG_GCCFG_VBDEN
504 sil_orw_mem((uint32_t *)(USBOTG_BASE(base)+TOFF_USBO_GCCFG), USB_OTG_GCCFG_VBDEN);
505 if(husb->Init.usb_otg_mode != USB_OTG_MODE_HOST){
506 if(husb->Init.vbus_sensing_enable == 0){
507 sil_andw_mem((uint32_t *)(USBOTG_BASE(base)+TOFF_USBO_GCCFG), USB_OTG_GCCFG_VBDEN);
508 sil_orw_mem((uint32_t *)(USBOTG_BASE(base)+TOFF_USBO_GOTGCTL), USB_OTG_GOTGCTL_BVALOEN);
509 sil_orw_mem((uint32_t *)(USBOTG_BASE(base)+TOFF_USBO_GOTGCTL), USB_OTG_GOTGCTL_BVALOVAL);
510 }
511 }
512#else
513 if(husb->Init.usb_otg_mode != USB_OTG_MODE_HOST){
514 sil_orw_mem((uint32_t *)(USBOTG_BASE(base)+TOFF_USBO_GCCFG), USB_OTG_GCCFG_VBUSBSEN);
515 if(husb->Init.vbus_sensing_enable == 0){
516 sil_orw_mem((uint32_t *)(USBOTG_BASE(base)+TOFF_USBO_GCCFG), USB_OTG_GCCFG_NOVBUSSENS);
517 }
518 }
519 else{
520 sil_andw_mem((uint32_t *)(USBOTG_BASE(base)+TOFF_USBO_GCCFG), USB_OTG_GCCFG_VBUSASEN);
521 sil_andw_mem((uint32_t *)(USBOTG_BASE(base)+TOFF_USBO_GCCFG), USB_OTG_GCCFG_VBUSBSEN);
522 sil_orw_mem((uint32_t *)(USBOTG_BASE(base)+TOFF_USBO_GCCFG), USB_OTG_GCCFG_NOVBUSSENS);
523 }
524#endif
525
526 /*
527 * リスタートPHYクロック
528 */
529 sil_wrw_mem((uint32_t *)(USBPGC_BASE(base)), 0);
530
531 /*
532 * GINTのオールマスク設定
533 */
534 sil_wrw_mem((uint32_t *)(USBOTG_BASE(base)+TOFF_USBO_GINTMSK), 0);
535
536 /*
537 * GINTオール割込みクリア
538 */
539 sil_wrw_mem((uint32_t *)(USBOTG_BASE(base)+TOFF_USBO_GINTSTS), 0xFFFFFFFF);
540 return husb;
541}
542
543/*
544 * USB OTGハードウェア停止
545 * parameter1 husb USBハンドラへのポインタ
546 * return 常にE_OK
547 */
548ER
549usbo_deinit(USB_OTG_Handle_t *husb)
550{
551 if(husb->base == TADR_USB_OTGFS_BASE)
552 sil_andw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_USBFS), RCC_USBFSEN);
553 else
554 sil_andw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_USBHS), RCC_USBHSEN);
555 return E_OK;
556}
557
558/*
559 * USB OTG割込み設定
560 * parameter1 husb USBハンドラへのポインタ
561 * return 常にE_OK
562 */
563ER
564usbo_setupint(USB_OTG_Handle_t *husb)
565{
566 uint32_t base = husb->base;
567 uint32_t intmsk = USB_OTG_GINTMSK_PXFRM_IISOOXFRM | USB_OTG_GINTMSK_WUIM;
568
569 /*
570 * 割込み禁止
571 */
572 sil_wrw_mem((uint32_t *)(USBOTG_BASE(base)+TOFF_USBO_GINTMSK), 0);
573
574 /*
575 * 割込みペンディングクリア
576 */
577 sil_wrw_mem((uint32_t *)(USBOTG_BASE(base)+TOFF_USBO_GINTSTS), 0xFFFFFFFF);
578
579 /*
580 * DMA割込み許可
581 */
582 if(husb->Init.dma_enable == 0){
583 intmsk |= USB_OTG_GINTMSK_RXFLVLM;
584 }
585
586 /*
587 * USB HOST割込み許可
588 */
589 if(husb->Init.usb_otg_mode != USB_OTG_MODE_DEVICE){
590 intmsk |= (USB_OTG_GINTMSK_PRTIM | USB_OTG_GINTMSK_HCIM |\
591 USB_OTG_GINTMSK_SOFM | USB_OTG_GINTSTS_DISCINT);
592 }
593 /*
594 * USB DEVICE割込み許可
595 */
596 if(husb->Init.usb_otg_mode != USB_OTG_MODE_HOST){
597 intmsk |= (USB_OTG_GINTMSK_USBSUSPM | USB_OTG_GINTMSK_USBRST |\
598 USB_OTG_GINTMSK_ENUMDNEM | USB_OTG_GINTMSK_IEPINT |\
599 USB_OTG_GINTMSK_OEPINT | USB_OTG_GINTMSK_IISOIXFRM);
600 }
601
602 /*
603 * SOF割込み許可設定
604 */
605 if(husb->Init.sof_enable){
606 intmsk |= USB_OTG_GINTMSK_SOFM;
607 }
608
609 /*
610 * SENSE ENABLE割込み許可設定
611 */
612 if(husb->Init.vbus_sensing_enable == 1){
613 intmsk |= (USB_OTG_GINTMSK_SRQIM | USB_OTG_GINTMSK_OTGINT);
614 }
615 sil_wrw_mem((uint32_t *)(USBOTG_BASE(base)+TOFF_USBO_GINTMSK), intmsk);
616 return E_OK;
617}
618
619/*
620 * USBコア部リセット
621 * parameter1 husb USBロジックベースアドレス
622 * return 正常終了:E_OK タイムアウト:E_TMOUT
623 */
624static ER
625USB_CoreReset(uint32_t base)
626{
627 uint32_t tick = 0;
628
629 /*
630 * AHBマスターのIDLEステート待ち
631 */
632 do{
633 if(++tick > RESET_TIMEOUT)
634 return E_TMOUT;
635 sil_dly_nse(10*1000);
636 }
637 while ((sil_rew_mem((uint32_t *)(USBOTG_BASE(base)+TOFF_USBO_GRSTCTL)) & USB_OTG_GRSTCTL_AHBIDL) == 0);
638
639 /*
640 * コア、ソフトリセット要求
641 */
642 tick = 0;
643 sil_orw_mem((uint32_t *)(USBOTG_BASE(base)+TOFF_USBO_GRSTCTL), USB_OTG_GRSTCTL_CSRST);
644 do{
645 if(++tick > RESET_TIMEOUT)
646 return E_TMOUT;
647 sil_dly_nse(10*1000);
648 }
649 while ((sil_rew_mem((uint32_t *)(USBOTG_BASE(base)+TOFF_USBO_GRSTCTL)) & USB_OTG_GRSTCTL_CSRST) != 0);
650 return E_OK;
651}
652
653/*
654 * パケットデータ書き込み
655 * parameter1 base USB OTGレジスタベースアドレス
656 * parameter2 src 書き込みデータのポインタ
657 * parameter3 ch_ep_num エンドポイント、または、チャネル番号
658 * parameter4 len データ長
659 * parameter5 dma DMAモード(0:none-DMA、1:DMA)
660 */
661static void
662usbo_writePacket(uint32_t base, uint8_t *src, uint8_t ch_ep_num, uint16_t len, uint8_t dma)
663{
664 uint32_t count32b = 0 , i = 0;
665
666 if(dma == 0U){
667 count32b = (len + 3) / 4;
668 for(i = 0 ; i < count32b; i++, src += 4){
669 sil_wrw_mem((uint32_t *)(USBD_FIFO(base, ch_ep_num)), get_packet_data(src));
670 }
671 }
672}
673
674/*
675 * パケットデータ読み込み
676 * parameter1 base USB OTGレジスタベースアドレス
677 * parameter2 dest 読み込みデータのポインタ
678 * parameter3 len データ長
679 */
680static void *
681usbo_readPacket(uint32_t base, uint8_t *dest, uint16_t len)
682{
683 uint32_t i=0U;
684 uint32_t count32b = (len + 3U) / 4U;
685 uint32_t data;
686
687 for(i = 0 ; i < count32b; i++, dest += 4){
688 data = sil_rew_mem((uint32_t *)(USBD_FIFO(base, 0)));
689 dest[0] = (data & 0xff);
690 dest[1] = (data >> 8) & 0xff;
691 dest[2] = (data >> 16) & 0xff;
692 dest[3] = (data >> 24) & 0xff;
693 }
694 return ((void *)dest);
695}
696
697/*
698 * USB HOSTのカレントフレーム番号を取り出す
699 * parameter1 USBハンドラへのポインタ
700 * return ハンドラ番号
701*/
702uint32_t
703usbo_getcurrentframe(USB_OTG_Handle_t *husb)
704{
705 return (sil_rew_mem((uint32_t *)(USBH_BASE(husb->base)+TOFF_USBH_HFNUM)) & USB_OTG_HFNUM_FRNUM);
706}
707
708/*
709 * USB OTGの機能設定を行う
710 * parameter1 husb USBハンドラへのポインタ
711 * usb_otg_modeの設定:USB_OTG_MODE_DEVICE(USB DEVICE固定)
712 * USB_OTG_MODE_HOST(USB HOST固定)
713 * USB_OTG_MODE_DRD(デュアルモード)
714 * return 常にE_OK
715 */
716ER
717usbo_setcurrentmode(USB_OTG_Handle_t *husb)
718{
719 uint32_t base = husb->base;
720 uint32_t gusbcfg = sil_rew_mem((uint32_t *)(USBOTG_BASE(base)+TOFF_USBO_GUSBCFG));
721
722 gusbcfg &= ~(USB_OTG_GUSBCFG_FHMOD | USB_OTG_GUSBCFG_FDMOD);
723
724 if(husb->Init.usb_otg_mode == USB_OTG_MODE_HOST){
725 gusbcfg |= USB_OTG_GUSBCFG_FHMOD;
726 }
727 else if(husb->Init.usb_otg_mode == USB_OTG_MODE_DEVICE){
728 gusbcfg |= USB_OTG_GUSBCFG_FDMOD;
729 }
730 sil_wrw_mem((uint32_t *)(USBOTG_BASE(base)+TOFF_USBO_GUSBCFG), gusbcfg);
731 dly_tsk(50);
732 return E_OK;
733}
734
735/*
736 * USBコアの初期化
737 * parameter1 husb USBハンドラへのポインタ
738 * return 常にE_OK
739 */
740ER
741usbo_coreinit(USB_OTG_Handle_t *husb)
742{
743 uint32_t base = husb->base;
744
745 if(husb->Init.phy_itface == USB_PHY_ULPI){ /* ULPI-PHY select */
746 sil_andw_mem((uint32_t *)(USBOTG_BASE(base)+TOFF_USBO_GCCFG), USB_OTG_GCCFG_PWRDWN);
747
748 /*
749 * ULPI-PHY初期化
750 */
751 sil_andw_mem((uint32_t *)(USBOTG_BASE(base)+TOFF_USBO_GUSBCFG), (USB_OTG_GUSBCFG_TSDPS | USB_OTG_GUSBCFG_ULPIFSLS | USB_OTG_GUSBCFG_PHYSEL));
752
753 /*
754 * VBUSソース設定
755 */
756 sil_andw_mem((uint32_t *)(USBOTG_BASE(base)+TOFF_USBO_GUSBCFG), (USB_OTG_GUSBCFG_ULPIEVBUSD | USB_OTG_GUSBCFG_ULPIEVBUSI));
757 if(husb->Init.use_external_vbus == 1){
758 sil_orw_mem((uint32_t *)(USBOTG_BASE(base)+TOFF_USBO_GUSBCFG), USB_OTG_GUSBCFG_ULPIEVBUSD);
759 }
760 /*
761 * コアリセット
762 */
763 USB_CoreReset(base);
764 }
765 else{ /* Embedded PHY select */
766 /*
767 * Embedded FS-PHY選択
768 */
769 sil_orw_mem((uint32_t *)(USBOTG_BASE(base)+TOFF_USBO_GUSBCFG), USB_OTG_GUSBCFG_PHYSEL);
770
771 /*
772 * コアリセット
773 */
774 USB_CoreReset(base);
775
776 /*
777 * 電源ダウン解除
778 */
779 sil_wrw_mem((uint32_t *)(USBOTG_BASE(base)+TOFF_USBO_GCCFG), USB_OTG_GCCFG_PWRDWN);
780 }
781
782 /*
783 * DMAモード設定
784 */
785 if(husb->Init.dma_enable == 1){
786 sil_orw_mem((uint32_t *)(USBOTG_BASE(base)+TOFF_USBO_GAHBCFG), USB_OTG_GAHBCFG_DMAEN);
787 }
788 return E_OK;
789}
790
791/*
792 * USBグローバル割込み許可
793 * parameter1 husb USBハンドラへのポインタ
794 * return 常にE_OK
795 */
796ER
797usbo_enableglobalint(USB_OTG_Handle_t *husb)
798{
799 sil_orw_mem((uint32_t *)(USBOTG_BASE(husb->base)+TOFF_USBO_GAHBCFG), USB_OTG_GAHBCFG_GINT);
800 return E_OK;
801}
802
803/*
804 * USBグローバル割込み禁止
805 * parameter1 husb USBハンドラへのポインタ
806 * return 常にE_OK
807 */
808ER
809usbo_disableglobalint(USB_OTG_Handle_t *husb)
810{
811 sil_andw_mem((uint32_t *)(USBOTG_BASE(husb->base)+TOFF_USBO_GAHBCFG), USB_OTG_GAHBCFG_GINT);
812 return E_OK;
813}
814
815/*
816 * 送信FIFOのフラッシュ
817 * parameter1 husb USBハンドラへのポインタ
818 * return 正常終了:E_OK、タイムアウト:E_TMOUT
819 */
820ER
821usbo_flushTxFifo(USB_OTG_Handle_t *husb, uint32_t num)
822{
823 uint32_t base = husb->base;
824 uint32_t tick = 0;
825
826 sil_wrw_mem((uint32_t *)(USBOTG_BASE(base)+TOFF_USBO_GRSTCTL), (USB_OTG_GRSTCTL_TXFFLSH |(uint32_t)(num << 6)));
827 do{
828 if(++tick > RESET_TIMEOUT)
829 return E_TMOUT;
830 sil_dly_nse(10*1000);
831 }while ((sil_rew_mem((uint32_t *)(USBOTG_BASE(base)+TOFF_USBO_GRSTCTL)) & USB_OTG_GRSTCTL_TXFFLSH) != 0);
832 return E_OK;
833}
834
835/*
836 * 受信FIFOのフラッシュ
837 * parameter1 husb USBハンドラへのポインタ
838 * return 正常終了:E_OK、タイムアウト:E_TMOUT
839 */
840ER
841usbo_flushRxFifo(USB_OTG_Handle_t *husb)
842{
843 uint32_t base = husb->base;
844 uint32_t tick = 0;
845
846 sil_wrw_mem((uint32_t *)(USBOTG_BASE(base)+TOFF_USBO_GRSTCTL), USB_OTG_GRSTCTL_RXFFLSH);
847 do{
848 if(++tick > RESET_TIMEOUT)
849 return E_TMOUT;
850 sil_dly_nse(10*1000);
851 }while((sil_rew_mem((uint32_t *)(USBOTG_BASE(base)+TOFF_USBO_GRSTCTL)) & USB_OTG_GRSTCTL_RXFFLSH) != 0);
852
853#ifdef USB_OTG_GCCFG_VBDEN
854 sil_orw_mem((uint32_t *)(USBOTG_BASE(base)+TOFF_USBO_GCCFG), USB_OTG_GCCFG_VBDEN);
855#endif
856 return E_OK;
857}
858
859/*
860 * FIFOの初期化
861 * parameter1 husb USBハンドラへのポインタ
862 * return 常にE_OK
863 */
864ER
865usbo_initFiFo(USB_OTG_Handle_t *husb)
866{
867 unsigned int ep;
868 unsigned int addr;
869 uint32_t base = husb->base;
870 uint32_t val;
871
872 /*
873 * RX/NPTX FIFOサイズ設定
874 */
875 sil_wrw_mem((uint32_t *)(USBOTG_BASE(base)+TOFF_USBO_GRXFSIZ), husb->pcd_np_g_tx_fifo_sz);
876 sil_wrw_mem((uint32_t *)(USBOTG_BASE(base)+TOFF_USBO_DIEPTXF0_HNPTXFSIZ),
877 (husb->pcd_np_g_tx_fifo_sz<<16) | husb->pcd_rx_fifo_sz);
878
879 /*
880 * すべてのTX FIFO設定
881 */
882 addr = husb->pcd_rx_fifo_sz + husb->pcd_np_g_tx_fifo_sz;
883 for(ep = 1; ep < MAX_EPS_CHANNELS; ep++) {
884 if(husb->pcd_tx_fifo_sz[ep] == 0){
885 sil_wrw_mem((uint32_t *)(USBOTG_BASE(base)+TOFF_USBO_DIEPTXF+(ep-1)*4), 0);
886 continue;
887 }
888 val = addr | husb->pcd_tx_fifo_sz[ep] << 16;
889 if((addr + husb->pcd_tx_fifo_sz[ep]) > husb->fifo_mem)
890 syslog_1(LOG_ERROR, "insufficient fifo memory(%d)", ep);
891 addr += husb->pcd_tx_fifo_sz[ep];
892 sil_wrw_mem((uint32_t *)(USBOTG_BASE(base)+TOFF_USBO_DIEPTXF+(ep-1)*4), val);
893 }
894
895 /*
896 * FIFOフラッシュ処理
897 */
898 usbo_flushTxFifo(husb, 0x10);
899 usbo_flushRxFifo(husb);
900 return E_OK;
901}
902
903/*******************************************************************************
904 USB HOST関数
905*******************************************************************************/
906/*
907 * USB HOST初期化
908 * parameter1 husb USBハンドラへのポインタ
909 * return 常にE_OK
910 */
911ER
912usbo_hostinit(USB_OTG_Handle_t *husb)
913{
914 uint32_t base = husb->base;
915 bool_t forced;
916 uint32_t val, i;
917
918 /* Disable the FS/LS support mode only */
919 if((husb->Init.speed == USB_SPEED_FULL) && (base != TADR_USB_OTGFS_BASE)){
920 sil_orw_mem((uint32_t *)(USBH_BASE(base)+TOFF_USBH_HCFG), USB_OTG_HCFG_FSLSS);
921 }
922 else{
923 sil_andw_mem((uint32_t *)(USBH_BASE(base)+TOFF_USBH_HCFG), USB_OTG_HCFG_FSLSS);
924 }
925
926 /*
927 * HOST RX-FIFOサイズ設定
928 */
929 forced = usbo_force_mode_if_needed(husb, true);
930 sil_wrw_mem((uint32_t *)(USBOTG_BASE(base)+TOFF_USBO_GRXFSIZ), husb->pcd_np_g_tx_fifo_sz);
931 sil_wrw_mem((uint32_t *)(USBOTG_BASE(base)+TOFF_USBO_DIEPTXF0_HNPTXFSIZ),
932 (husb->pcd_np_g_tx_fifo_sz<<16) | husb->pcd_rx_fifo_sz);
933 val = (husb->pcd_rx_fifo_sz + husb->pcd_np_g_tx_fifo_sz) | husb->pcd_tx_fifo_sz[1] << 16;
934 sil_wrw_mem((uint32_t *)(USBOTG_BASE(base)+TOFF_USBO_HPTXFSIZ), val);
935
936 /*
937 * FIFOフラッシュ
938 */
939 usbo_flushTxFifo(husb, 0x10U); /* all Tx FIFOs */
940 usbo_flushRxFifo(husb);
941 if(forced)
942 usbo_clear_force_mode(husb);
943
944 /*
945 * チャネル割込みクリアとマスク
946 */
947 for (i = 0 ; i < husb->Init.host_channels; i++){
948 sil_wrw_mem((uint32_t *)(USBHC_BASE(base, i)+TOFF_USBHC_HCINT), 0xFFFFFFFFU);
949 sil_wrw_mem((uint32_t *)(USBHC_BASE(base, i)+TOFF_USBHC_HCINTMSK), 0U);
950 }
951
952 /*
953 * L3ステート設定
954 */
955 husb->lx_state = DWC2_L0;
956
957 /*
958 * HOST VBUS設定
959 */
960 usbo_drivevbus(husb, 1);
961 dly_tsk(200U);
962 usbo_setupint(husb);
963 return E_OK;
964}
965
966/*
967 * HOSTコア開始要求
968 * parameter1 husb USBハンドラへのポインタ
969 * return 常にE_OK
970 */
971ER
972usbo_starthost(USB_OTG_Handle_t *husb)
973{
974 if(husb->Init.usb_otg_mode == USB_OTG_MODE_DRD
975 && husb->lx_state != DWC2_L0){
976 usbo_hostinit(husb);
977 dly_tsk(25);
978 usbo_devdisconnect(husb);
979 dly_tsk(3);
980 usbo_devconnect(husb);
981 }
982 husb->lx_state = DWC2_L0;
983 return E_OK;
984}
985
986/*
987 * HOSTコア停止要求
988 * parameter1 husb USBハンドラへのポインタ
989 * return 常にE_OK
990 */
991ER
992usbo_stophost(USB_OTG_Handle_t *husb)
993{
994 uint32_t base = husb->base;
995 uint32_t tick = 0;
996 int i;
997
998 usbo_disableglobalint(husb);
999
1000 /*
1001 * FIFOフラッシュ
1002 */
1003 if(husb->Init.usb_otg_mode == USB_OTG_MODE_HOST){
1004 usbo_flushTxFifo(husb, 0x10U);
1005 usbo_flushRxFifo(husb);
1006 }
1007
1008 /*
1009 * HOSTチャネルキュークリア
1010 */
1011 for(i = 0 ; i <= 15 ; i++){
1012 sil_modw_mem((uint32_t *)(USBHC_BASE(base, i)+TOFF_USBHC_HCCHAR), (USB_OTG_HCCHAR_CHENA|USB_OTG_HCCHAR_EPDIR), USB_OTG_HCCHAR_CHDIS);
1013 }
1014
1015 /*
1016 * HOSTチャネルHALT
1017 */
1018 for(i = 0, tick = 0 ; i <= 15 ; i++){
1019 sil_modw_mem((uint32_t *)(USBHC_BASE(base, i)+TOFF_USBHC_HCCHAR), USB_OTG_HCCHAR_EPDIR, (USB_OTG_HCCHAR_CHDIS|USB_OTG_HCCHAR_CHENA));
1020 do{
1021 if(++tick > HALT_TIMEOUT)
1022 break;
1023 sil_dly_nse(10*1000);
1024 }while((sil_rew_mem((uint32_t *)(USBHC_BASE(base, i)+TOFF_USBHC_HCCHAR)) & USB_OTG_HCCHAR_CHENA) != 0);
1025 }
1026
1027 /*
1028 * USBホスト用の割込みクリア
1029 */
1030 sil_wrw_mem((uint32_t *)(USBH_BASE(base)+TOFF_USBH_HAINT), 0xFFFFFFFFU);
1031 sil_wrw_mem((uint32_t *)(USBOTG_BASE(base)+TOFF_USBO_GINTSTS), 0xFFFFFFFFU);
1032 husb->lx_state = DWC2_L3;
1033 return E_OK;
1034}
1035
1036/*
1037 * HOSTチャネルの初期化
1038 * parameter1 husb USBハンドラへのポインタ
1039 * parameter2 ch_num チャネル番号(1-15)
1040 * parameter3 epnum エンドポイント番号(1-15)
1041 * return 常にE_OK
1042 */
1043ER
1044usbo_hc_init(USB_OTG_Handle_t *husb, uint8_t ch_num, uint8_t epnum)
1045{
1046 uint32_t base = husb->base;
1047 uint8_t address = husb->hc[ch_num].dev_addr;
1048 uint8_t speed = husb->hc[ch_num].speed;
1049 uint8_t ep_type = husb->hc[ch_num].ep_type;
1050 uint16_t mps = husb->hc[ch_num].max_packet;
1051 uint32_t hcint = 0;
1052
1053 /*
1054 * チャネルの割込みクリア
1055 */
1056 sil_wrw_mem((uint32_t *)(USBHC_BASE(base, ch_num)+TOFF_USBHC_HCINT), 0xFFFFFFFFU);
1057
1058 /*
1059 * エンドポイント型に従う初期化
1060 */
1061 switch (ep_type) {
1062 case EP_TYPE_CTRL:
1063 case EP_TYPE_BULK:
1064 hcint = USB_OTG_HCINTMSK_XFRCM | USB_OTG_HCINTMSK_STALLM |\
1065 USB_OTG_HCINTMSK_TXERRM | USB_OTG_HCINTMSK_DTERRM |\
1066 USB_OTG_HCINTMSK_AHBERR | USB_OTG_HCINTMSK_NAKM;
1067
1068 if(epnum & 0x80U){
1069 hcint |= USB_OTG_HCINTMSK_BBERRM;
1070 }
1071 else{
1072 if(base != TADR_USB_OTGFS_BASE){
1073 hcint |= USB_OTG_HCINTMSK_NYET | USB_OTG_HCINTMSK_ACKM;
1074 }
1075 }
1076 break;
1077
1078 case EP_TYPE_INTR:
1079 hcint = USB_OTG_HCINTMSK_XFRCM | USB_OTG_HCINTMSK_STALLM |\
1080 USB_OTG_HCINTMSK_TXERRM | USB_OTG_HCINTMSK_DTERRM |\
1081 USB_OTG_HCINTMSK_NAKM | USB_OTG_HCINTMSK_AHBERR | USB_OTG_HCINTMSK_FRMORM;
1082
1083 if(epnum & 0x80)
1084 hcint |= USB_OTG_HCINTMSK_BBERRM;
1085 break;
1086 case EP_TYPE_ISOC:
1087 hcint = USB_OTG_HCINTMSK_XFRCM | USB_OTG_HCINTMSK_ACKM |\
1088 USB_OTG_HCINTMSK_AHBERR | USB_OTG_HCINTMSK_FRMORM;
1089
1090 if(epnum & 0x80)
1091 hcint |= USB_OTG_HCINTMSK_TXERRM | USB_OTG_HCINTMSK_BBERRM;
1092 break;
1093 }
1094 sil_wrw_mem((uint32_t *)(USBHC_BASE(base, ch_num)+TOFF_USBHC_HCINTMSK), hcint);
1095
1096 /*
1097 * HOSTチャネル割込みマスク解除
1098 */
1099 sil_orw_mem((uint32_t *)(USBH_BASE(base)+TOFF_USBH_HAINTMSK), (1 << ch_num));
1100
1101 /*
1102 * HOSTチャネル割込み許可
1103 */
1104 sil_orw_mem((uint32_t *)(USBOTG_BASE(base)+TOFF_USBO_GINTMSK), USB_OTG_GINTMSK_HCIM);
1105
1106 /*
1107 * HCCHARレジスタ設定
1108 */
1109 sil_wrw_mem((uint32_t *)(USBHC_BASE(base, ch_num)+TOFF_USBHC_HCCHAR), (((address << 22U) & USB_OTG_HCCHAR_DAD) |\
1110 (((epnum & 0x7FU)<< 11U) & USB_OTG_HCCHAR_EPNUM)|\
1111 ((((epnum & 0x80U) == 0x80U)<< 15U) & USB_OTG_HCCHAR_EPDIR)|\
1112 (((speed == USB_SPEED_LOW)<< 17U) & USB_OTG_HCCHAR_LSDEV)|\
1113 ((ep_type << 18U) & USB_OTG_HCCHAR_EPTYP)|\
1114 (mps & USB_OTG_HCCHAR_MPSIZ)));
1115
1116 if(ep_type == EP_TYPE_INTR){
1117 sil_orw_mem((uint32_t *)(USBHC_BASE(base, ch_num)+TOFF_USBHC_HCCHAR), USB_OTG_HCCHAR_ODDFRM);
1118 }
1119 return E_OK;
1120}
1121
1122/*
1123 * HOSTコアスピードを取り出す
1124 * parameter1 husb USBハンドラへのポインタ
1125 * return speed USB_SPEED_HIGH(High speed)
1126 * USB_SPEED_FULL(Full speed)
1127 * USB_SPEED_LOW(Low speed)
1128 */
1129uint32_t
1130usbo_gethostspeed(USB_OTG_Handle_t *husb)
1131{
1132 volatile uint32_t hprt0;
1133
1134 hprt0 = sil_rew_mem((uint32_t*)(USBPRT_BASE(husb->base)));
1135 return ((hprt0 & USB_OTG_HPRT_PSPD) >> 17);
1136}
1137
1138/*
1139 * HOSTチャネル送信要求
1140 * parameter1 husb USBハンドラへのポインタ
1141 * parameter2 ch_num チャネル番号(1-15)
1142 * return 常にE_OK
1143 */
1144ER
1145usbo_hc_startxfer(USB_OTG_Handle_t *husb, uint8_t ch_num)
1146{
1147 USB_OTG_HCTypeDef *hc = &husb->hc[ch_num];
1148 uint32_t base = husb->base;
1149 uint8_t is_oddframe = 0U;
1150 uint16_t len_words = 0U;
1151 uint16_t num_packets = 0U;
1152 uint16_t max_hc_pkt_count = 256U;
1153
1154 if((base != TADR_USB_OTGFS_BASE) && (hc->speed == USB_SPEED_HIGH)){
1155 if((husb->Init.dma_enable == 0) && (hc->do_ping == 1)){
1156 /*
1157 * Do Ping
1158 */
1159 sil_wrw_mem((uint32_t *)(USBHC_BASE(base, hc->ch_num)+TOFF_USBHC_HCTSIZ), ((1 << 19) & USB_OTG_HCTSIZ_PKTCNT) | USB_OTG_HCTSIZ_DOPING);
1160 sil_modw_mem((uint32_t *)(USBHC_BASE(base, hc->ch_num)+TOFF_USBHC_HCCHAR), USB_OTG_HCCHAR_CHDIS, USB_OTG_HCCHAR_CHENA);
1161 return E_OK;
1162 }
1163 else if(husb->Init.dma_enable == 1){
1164 sil_andw_mem((uint32_t *)(USBHC_BASE(base, hc->ch_num)+TOFF_USBHC_HCINTMSK), (USB_OTG_HCINTMSK_NYET | USB_OTG_HCINTMSK_ACKM));
1165 hc->do_ping = 0U;
1166 }
1167 }
1168
1169 /*
1170 * パケット数、転送長の計算
1171 */
1172 if(hc->xfer_len > 0){
1173 num_packets = (hc->xfer_len + hc->max_packet - 1U) / hc->max_packet;
1174
1175 if(num_packets > max_hc_pkt_count){
1176 num_packets = max_hc_pkt_count;
1177 hc->xfer_len = num_packets * hc->max_packet;
1178 }
1179 }
1180 else{
1181 num_packets = 1;
1182 }
1183 if(hc->ep_is_in){
1184 hc->xfer_len = num_packets * hc->max_packet;
1185 }
1186
1187 /*
1188 * HCTSIZレジスタ設定
1189 */
1190 sil_wrw_mem((uint32_t *)(USBHC_BASE(base, hc->ch_num)+TOFF_USBHC_HCTSIZ), (((hc->xfer_len) & USB_OTG_HCTSIZ_XFRSIZ)) |\
1191 ((num_packets << 19U) & USB_OTG_HCTSIZ_PKTCNT) | (((hc->data_pid) << 29U) & USB_OTG_HCTSIZ_DPID));
1192
1193 if(husb->Init.dma_enable){
1194 flushinvalidatedcache_by_addr(((uint8_t *)hc->xfer_buff), hc->xfer_len);
1195 sil_wrw_mem((uint32_t *)(USBHC_BASE(base, hc->ch_num)+TOFF_USBHC_HCDMA), (uint32_t)hc->xfer_buff);
1196 }
1197
1198 /*
1199 * EVEN/ODDパケット設定
1200 */
1201 is_oddframe = (sil_rew_mem((uint32_t *)(USBH_BASE(base)+TOFF_USBH_HFNUM)) & 0x01U) ? 0U : 1U;
1202 sil_andw_mem((uint32_t *)(USBHC_BASE(base, hc->ch_num)+TOFF_USBHC_HCCHAR), USB_OTG_HCCHAR_ODDFRM);
1203 sil_orw_mem((uint32_t *)(USBHC_BASE(base, hc->ch_num)+TOFF_USBHC_HCCHAR), (is_oddframe << 29U));
1204
1205 /*
1206 * HOSTチャネルを有効化
1207 */
1208 sil_modw_mem((uint32_t *)(USBHC_BASE(base, hc->ch_num)+TOFF_USBHC_HCCHAR), USB_OTG_HCCHAR_CHDIS, USB_OTG_HCCHAR_CHENA);
1209
1210 if(husb->Init.dma_enable == 0){ /* none DMAモード */
1211 if((hc->ep_is_in == 0U) && (hc->xfer_len > 0U)){
1212 switch(hc->ep_type) {
1213 case EP_TYPE_CTRL: /* NON PERIODIC転送 */
1214 case EP_TYPE_BULK:
1215 len_words = (hc->xfer_len + 3) / 4;
1216 /*
1217 * FIFO長を超える場合、NPTXFEMPTY割込みを設定
1218 */
1219 if(len_words > (sil_rew_mem((uint32_t *)(USBOTG_BASE(base)+TOFF_USBO_HNPTXSTS)) & 0xFFFFU)){
1220 sil_orw_mem((uint32_t *)(USBOTG_BASE(base)+TOFF_USBO_GINTMSK), USB_OTG_GINTMSK_NPTXFEM);
1221 }
1222 break;
1223 case EP_TYPE_INTR: /* PERIODIC 転送 */
1224 case EP_TYPE_ISOC:
1225 len_words = (hc->xfer_len + 3) / 4;
1226 /*
1227 * FIFO長を超える場合、PTXFEMPTY割込みを設定
1228 */
1229 if(len_words > (sil_rew_mem((uint32_t *)(USBH_BASE(base)+TOFF_USBH_HPTXSTS)) & 0xFFFFU)){ /* split the transfer */
1230 sil_orw_mem((uint32_t *)(USBOTG_BASE(base)+TOFF_USBO_GINTMSK), USB_OTG_GINTMSK_PTXFEM);
1231 }
1232 break;
1233 default:
1234 break;
1235 }
1236
1237 /*
1238 * パケット書き込み
1239 */
1240 usbo_writePacket(base, hc->xfer_buff, hc->ch_num, hc->xfer_len, 0);
1241 }
1242 }
1243 return E_OK;
1244}
1245
1246/*
1247 * HOSTチャネルをHALTする
1248 * parameter1 husb USBハンドラへのポインタ
1249 * parameter2 チャネル番号(1-15)
1250 * return 常にE_OK
1251 */
1252ER
1253usbo_hc_halt(USB_OTG_Handle_t *husb, uint8_t ch_num)
1254{
1255 uint32_t base = husb->base;
1256 uint32_t tick = 0;
1257
1258 /* HCCHARコントロールモード */
1259 if((((sil_rew_mem((uint32_t *)(USBHC_BASE(base, ch_num)+TOFF_USBHC_HCCHAR)) & USB_OTG_HCCHAR_EPTYP) >> 18) == HCCHAR_CTRL)
1260 || ((((sil_rew_mem((uint32_t *)(USBHC_BASE(base, ch_num)+TOFF_USBHC_HCCHAR)) & USB_OTG_HCCHAR_EPTYP) >> 18) == HCCHAR_BULK))){
1261 sil_orw_mem((uint32_t *)(USBHC_BASE(base, ch_num)+TOFF_USBHC_HCCHAR), USB_OTG_HCCHAR_CHDIS);
1262 if((sil_rew_mem((uint32_t *)(USBOTG_BASE(base)+TOFF_USBO_HNPTXSTS)) & 0xFF0000U) == 0){
1263 sil_andw_mem((uint32_t *)(USBHC_BASE(base, ch_num)+TOFF_USBHC_HCCHAR), USB_OTG_HCCHAR_CHENA);
1264 sil_orw_mem((uint32_t *)(USBHC_BASE(base, ch_num)+TOFF_USBHC_HCCHAR), USB_OTG_HCCHAR_CHENA);
1265 do{
1266 if(++tick > HALT_TIMEOUT)
1267 break;
1268 sil_dly_nse(10*1000);
1269 }while((sil_rew_mem((uint32_t *)(USBHC_BASE(base, ch_num)+TOFF_USBHC_HCCHAR)) & USB_OTG_HCCHAR_CHENA) != 0);
1270 }
1271 else{
1272 sil_orw_mem((uint32_t *)(USBHC_BASE(base, ch_num)+TOFF_USBHC_HCCHAR), USB_OTG_HCCHAR_CHENA);
1273 }
1274 }
1275 else{ /* その他 */
1276 sil_orw_mem((uint32_t *)(USBHC_BASE(base, ch_num)+TOFF_USBHC_HCCHAR), USB_OTG_HCCHAR_CHDIS);
1277 if((sil_rew_mem((uint32_t *)(USBH_BASE(base)+TOFF_USBH_HPTXSTS)) & 0xFFFF) == 0){
1278 sil_andw_mem((uint32_t *)(USBHC_BASE(base, ch_num)+TOFF_USBHC_HCCHAR), USB_OTG_HCCHAR_CHENA);
1279 sil_orw_mem((uint32_t *)(USBHC_BASE(base, ch_num)+TOFF_USBHC_HCCHAR), USB_OTG_HCCHAR_CHENA);
1280 do{
1281 if(++tick > HALT_TIMEOUT)
1282 break;
1283 sil_dly_nse(10*1000);
1284 }while((sil_rew_mem((uint32_t *)(USBHC_BASE(base, ch_num)+TOFF_USBHC_HCCHAR)) & USB_OTG_HCCHAR_CHENA) != 0);
1285 }
1286 else{
1287 sil_orw_mem((uint32_t *)(USBHC_BASE(base, ch_num)+TOFF_USBHC_HCCHAR), USB_OTG_HCCHAR_CHENA);
1288 }
1289 }
1290 return E_OK;
1291}
1292
1293/*
1294 * USB OTG HOSTポートリセット
1295 * parameter1 husb USBハンドラへのポインタ
1296 * return 常にE_OK
1297 */
1298ER
1299usbo_resetport(USB_OTG_Handle_t *husb)
1300{
1301 uint32_t base = husb->base;
1302 volatile uint32_t hprt0;
1303
1304 hprt0 = sil_rew_mem((uint32_t*)(USBPRT_BASE(base)));
1305 hprt0 &= ~(USB_OTG_HPRT_PENA | USB_OTG_HPRT_PCDET | USB_OTG_HPRT_PENCHNG | USB_OTG_HPRT_POCCHNG);
1306
1307 sil_wrw_mem((uint32_t*)(USBPRT_BASE(base)), (USB_OTG_HPRT_PRST | hprt0));
1308 dly_tsk (10); /* See Note #1 */
1309 sil_wrw_mem((uint32_t*)(USBPRT_BASE(base)), (~(USB_OTG_HPRT_PRST) & hprt0));
1310 return E_OK;
1311}
1312
1313/*
1314 * USB HOST VBUSの有効、無効設定
1315 * parameter1 husb USBハンドラへのポインタ
1316 * parameter2 state 1:VBUS-ACTIVE 0:VBUS-INACTIVE
1317 * return 常にE_OK
1318 */
1319ER
1320usbo_drivevbus(USB_OTG_Handle_t *husb, uint8_t state)
1321{
1322 uint32_t base = husb->base;
1323 volatile uint32_t hprt0;
1324
1325 hprt0 = sil_rew_mem((uint32_t*)(USBPRT_BASE(base)));
1326 hprt0 &= ~(USB_OTG_HPRT_PENA | USB_OTG_HPRT_PCDET | USB_OTG_HPRT_PENCHNG | USB_OTG_HPRT_POCCHNG);
1327
1328 if(((hprt0 & USB_OTG_HPRT_PPWR) == 0) && (state == 1)){
1329 sil_wrw_mem((uint32_t*)(USBPRT_BASE(base)), (USB_OTG_HPRT_PPWR | hprt0));
1330 }
1331 if(((hprt0 & USB_OTG_HPRT_PPWR) != 0) && (state == 0)){
1332 sil_wrw_mem((uint32_t*)(USBPRT_BASE(base)), ((~USB_OTG_HPRT_PPWR) & hprt0));
1333 }
1334 return E_OK;
1335}
1336
1337/*
1338 * HOST EXTERNAL VBUSの有効、無効設定
1339 * parameter1 husb USBハンドラへのポインタ
1340 * parameter2 state 0:VBUS-ACTIVE 1:VBUS-INACTIVE
1341 */
1342void
1343usbo_driveextvbus(USB_OTG_Handle_t *husb, uint8_t state)
1344{
1345#if defined(FS_EVBUS_PINNO)
1346 if(husb->base == TADR_USB_OTGFS_BASE){
1347 if(state == 0)
1348 sil_wrw_mem((uint32_t *)(TADR_GPIOG_BASE+TOFF_GPIO_BSRR), (1<<(FS_EVBUS_PINNO+16)));
1349 else
1350 sil_wrw_mem((uint32_t *)(TADR_GPIOG_BASE+TOFF_GPIO_BSRR), (1<<(FS_EVBUS_PINNO)));
1351 }
1352#endif
1353}
1354
1355/*
1356 * FSLSPClkSel設定
1357 * parameter1 husb USBハンドラへのポインタ
1358 * parameter2 freq クロック周波数(48MHz,6MHzのみ有効)
1359 */
1360static void
1361usbo_initFSLSPClkSel(USB_OTG_Handle_t *husb, uint32_t freq)
1362{
1363 uint32_t base = husb->base;
1364 uint32_t hcfg = sil_rew_mem((uint32_t *)(USBH_BASE(base)+TOFF_USBH_HCFG));
1365 hcfg &= ~USB_OTG_HCFG_FSLSPCS;
1366 if(freq == 48000)
1367 hcfg |= USB_OTG_HCFG_FSLSPCS_0;
1368 else if(freq == 6000)
1369 hcfg |= USB_OTG_HCFG_FSLSPCS_1;
1370 sil_wrw_mem((uint32_t *)(USBH_BASE(base)+TOFF_USBH_HCFG), hcfg);
1371
1372 if(freq == 48000 || freq == 6000){
1373 sil_wrw_mem((uint32_t *)(USBH_BASE(base)+TOFF_USBH_HFIR), freq);
1374 }
1375}
1376
1377/*
1378 * HOSTチャネル割込み要求
1379 * parameter1 husb USBハンドラへのポインタ
1380 * parameter2 chnum チャネル番号(1-15)
1381 */
1382static void
1383usbo_hc_in_irqhandler(USB_OTG_Handle_t *husb, uint8_t chnum)
1384{
1385 USB_OTG_HCTypeDef *hc = &husb->hc[chnum];
1386 uint32_t base = husb->base;
1387
1388 if(hc_int_status(base, chnum, USB_OTG_HCINT_AHBERR) != 0){
1389 clear_hc_int(base, chnum, USB_OTG_HCINT_AHBERR);
1390 sil_orw_mem((uint32_t *)(USBHC_BASE(base, chnum)+TOFF_USBHC_HCINTMSK), USB_OTG_HCINTMSK_CHHM);
1391 }
1392 else if(hc_int_status(base, chnum, USB_OTG_HCINT_ACK) != 0){
1393 clear_hc_int(base, chnum, USB_OTG_HCINT_ACK);
1394 }
1395 else if(hc_int_status(base, chnum, USB_OTG_HCINT_STALL) != 0){
1396 sil_orw_mem((uint32_t *)(USBHC_BASE(base, chnum)+TOFF_USBHC_HCINTMSK), USB_OTG_HCINTMSK_CHHM);
1397 hc->state = USBO_HC_STALL;
1398 usbo_hc_halt(husb, chnum);
1399 clear_hc_int(base, chnum, USB_OTG_HCINT_NAK);
1400 clear_hc_int(base, chnum, USB_OTG_HCINT_STALL);
1401 }
1402 else if(hc_int_status(base, chnum, USB_OTG_HCINT_DTERR) != 0){
1403 sil_orw_mem((uint32_t *)(USBHC_BASE(base, chnum)+TOFF_USBHC_HCINTMSK), USB_OTG_HCINTMSK_CHHM);
1404 usbo_hc_halt(husb, chnum);
1405 clear_hc_int(base, chnum, USB_OTG_HCINT_NAK);
1406 hc->state = USBO_HC_DATATGLERR;
1407 clear_hc_int(base, chnum, USB_OTG_HCINT_DTERR);
1408 }
1409
1410 if(hc_int_status(base, chnum, USB_OTG_HCINT_FRMOR) != 0){
1411 sil_orw_mem((uint32_t *)(USBHC_BASE(base, chnum)+TOFF_USBHC_HCINTMSK), USB_OTG_HCINTMSK_CHHM);
1412 usbo_hc_halt(husb, chnum);
1413 clear_hc_int(base, chnum, USB_OTG_HCINT_FRMOR);
1414 }
1415 else if(hc_int_status(base, chnum, USB_OTG_HCINT_XFRC) != 0){
1416 if (husb->Init.dma_enable){
1417 hc->xfer_count = hc->xfer_len - (sil_rew_mem((uint32_t *)(USBHC_BASE(base, chnum)+TOFF_USBHC_HCTSIZ)) & USB_OTG_HCTSIZ_XFRSIZ);
1418 }
1419
1420 hc->state = USBO_HC_XFRC;
1421 hc->err_count = 0;
1422 clear_hc_int(base, chnum, USB_OTG_HCINT_XFRC);
1423
1424 if((hc->ep_type == EP_TYPE_CTRL) || (hc->ep_type == EP_TYPE_BULK)){
1425 sil_orw_mem((uint32_t *)(USBHC_BASE(base, chnum)+TOFF_USBHC_HCINTMSK), USB_OTG_HCINTMSK_CHHM);
1426 usbo_hc_halt(husb, chnum);
1427 clear_hc_int(base, chnum, USB_OTG_HCINT_NAK);
1428 }
1429 else if(hc->ep_type == EP_TYPE_INTR){
1430 sil_orw_mem((uint32_t *)(USBHC_BASE(base, chnum)+TOFF_USBHC_HCCHAR), USB_OTG_HCCHAR_ODDFRM);
1431 husb->hc[chnum].urb_state = URB_DONE;
1432 if(husb->hostchangeurbcallback != NULL)
1433 husb->hostchangeurbcallback(husb, chnum, husb->hc[chnum].urb_state);
1434 }
1435 hc->toggle_in ^= 1U;
1436 }
1437 else if(hc_int_status(base, chnum, USB_OTG_HCINT_CHH) != 0){
1438 sil_andw_mem((uint32_t *)(USBHC_BASE(base, chnum)+TOFF_USBHC_HCINTMSK), USB_OTG_HCINTMSK_CHHM);
1439 if(hc->state == USBO_HC_XFRC){
1440 hc->urb_state = URB_DONE;
1441 }
1442 else if(hc->state == USBO_HC_STALL){
1443 hc->urb_state = URB_STALL;
1444 }
1445 else if((hc->state == USBO_HC_XACTERR) || (hc->state == USBO_HC_DATATGLERR)){
1446 if(hc->err_count++ > 3U){
1447 hc->err_count = 0;
1448 hc->urb_state = URB_ERROR;
1449 }
1450 else{
1451 hc->urb_state = URB_NOTREADY;
1452 }
1453
1454 /*
1455 * チャネルの再アクティブ
1456 */
1457 sil_modw_mem((uint32_t *)(USBHC_BASE(base, chnum)+TOFF_USBHC_HCCHAR), USB_OTG_HCCHAR_CHDIS, USB_OTG_HCCHAR_CHENA);
1458 }
1459 clear_hc_int(base, chnum, USB_OTG_HCINT_CHH);
1460 if(husb->hostchangeurbcallback != NULL)
1461 husb->hostchangeurbcallback(husb, chnum, husb->hc[chnum].urb_state);
1462 }
1463 else if(hc_int_status(base, chnum, USB_OTG_HCINT_TXERR) != 0){
1464 sil_orw_mem((uint32_t *)(USBHC_BASE(base, chnum)+TOFF_USBHC_HCINTMSK), USB_OTG_HCINTMSK_CHHM);
1465 hc->err_count++;
1466 hc->state = USBO_HC_XACTERR;
1467#if 1 /* ROI DEBUG */
1468 syslog_1(LOG_NOTICE, "## SET USBO_HC_XACTERR1 [%08x] ##", sil_rew_mem((uint32_t *)(USBHC_BASE(base, chnum)+TOFF_USBHC_HCINT)));
1469#endif /* ROI DEBUG */
1470 usbo_hc_halt(husb, chnum);
1471 clear_hc_int(base, chnum, USB_OTG_HCINT_TXERR);
1472 }
1473 else if(hc_int_status(base, chnum, USB_OTG_HCINT_NAK) != 0){
1474 if(hc->ep_type == EP_TYPE_INTR){
1475 sil_orw_mem((uint32_t *)(USBHC_BASE(base, chnum)+TOFF_USBHC_HCINTMSK), USB_OTG_HCINTMSK_CHHM);
1476 usbo_hc_halt(husb, chnum);
1477 }
1478 else if((hc->ep_type == EP_TYPE_CTRL) || (hc->ep_type == EP_TYPE_BULK)){
1479 /*
1480 * チャネルの再アクティブ
1481 */
1482 sil_modw_mem((uint32_t *)(USBHC_BASE(base, chnum)+TOFF_USBHC_HCCHAR), USB_OTG_HCCHAR_CHDIS, USB_OTG_HCCHAR_CHENA);
1483 }
1484 hc->state = USBO_HC_NAK;
1485 clear_hc_int(base, chnum, USB_OTG_HCINT_NAK);
1486 }
1487}
1488
1489/*
1490 * HOSTチャネルOUT割込み要求
1491 * parameter1 husb USBハンドラへのポインタ
1492 * parameter2 chnum チャネル番号(1-15)
1493 */
1494static void
1495usbo_hc_out_irqhandler(USB_OTG_Handle_t *husb, uint8_t chnum)
1496{
1497 USB_OTG_HCTypeDef *hc = &husb->hc[chnum];
1498 uint32_t base = husb->base;
1499
1500 if(hc_int_status(base, chnum, USB_OTG_HCINT_AHBERR) != 0){
1501 clear_hc_int(base, chnum, USB_OTG_HCINT_AHBERR);
1502 sil_orw_mem((uint32_t *)(USBHC_BASE(base, chnum)+TOFF_USBHC_HCINTMSK), USB_OTG_HCINTMSK_CHHM);
1503 }
1504 else if(hc_int_status(base, chnum, USB_OTG_HCINT_ACK) != 0){
1505 clear_hc_int(base, chnum, USB_OTG_HCINT_ACK);
1506 if(hc->do_ping == 1U){
1507 hc->state = USBO_HC_NYET;
1508 sil_orw_mem((uint32_t *)(USBHC_BASE(base, chnum)+TOFF_USBHC_HCINTMSK), USB_OTG_HCINTMSK_CHHM);
1509 usbo_hc_halt(husb, chnum);
1510 hc->urb_state = URB_NOTREADY;
1511 }
1512 }
1513 else if(hc_int_status(base, chnum, USB_OTG_HCINT_NYET) != 0){
1514 hc->state = USBO_HC_NYET;
1515 hc->err_count= 0;
1516 sil_orw_mem((uint32_t *)(USBHC_BASE(base, chnum)+TOFF_USBHC_HCINTMSK), USB_OTG_HCINTMSK_CHHM);
1517 usbo_hc_halt(husb, chnum);
1518 clear_hc_int(base, chnum, USB_OTG_HCINT_NYET);
1519 }
1520 else if(hc_int_status(base, chnum, USB_OTG_HCINT_FRMOR) != 0){
1521 sil_orw_mem((uint32_t *)(USBHC_BASE(base, chnum)+TOFF_USBHC_HCINTMSK), USB_OTG_HCINTMSK_CHHM);
1522 usbo_hc_halt(husb, chnum);
1523 clear_hc_int(base, chnum, USB_OTG_HCINT_FRMOR);
1524 }
1525 else if(hc_int_status(base, chnum, USB_OTG_HCINT_XFRC) != 0){
1526 hc->err_count = 0;
1527 sil_orw_mem((uint32_t *)(USBHC_BASE(base, chnum)+TOFF_USBHC_HCINTMSK), USB_OTG_HCINTMSK_CHHM);
1528 usbo_hc_halt(husb, chnum);
1529 clear_hc_int(base, chnum, USB_OTG_HCINT_XFRC);
1530 hc->state = USBO_HC_XFRC;
1531 }
1532 else if(hc_int_status(base, chnum, USB_OTG_HCINT_STALL) != 0){
1533 clear_hc_int(base, chnum, USB_OTG_HCINT_STALL);
1534 sil_orw_mem((uint32_t *)(USBHC_BASE(base, chnum)+TOFF_USBHC_HCINTMSK), USB_OTG_HCINTMSK_CHHM);
1535 usbo_hc_halt(husb, chnum);
1536 hc->state = USBO_HC_STALL;
1537 }
1538 else if(hc_int_status(base, chnum, USB_OTG_HCINT_NAK) != 0){
1539 hc->err_count = 0;
1540 sil_orw_mem((uint32_t *)(USBHC_BASE(base, chnum)+TOFF_USBHC_HCINTMSK), USB_OTG_HCINTMSK_CHHM);
1541 usbo_hc_halt(husb, chnum);
1542 hc->state = USBO_HC_NAK;
1543 clear_hc_int(base, chnum, USB_OTG_HCINT_NAK);
1544 }
1545 else if(hc_int_status(base, chnum,USB_OTG_HCINT_TXERR) != 0){
1546 sil_orw_mem((uint32_t *)(USBHC_BASE(base, chnum)+TOFF_USBHC_HCINTMSK), USB_OTG_HCINTMSK_CHHM);
1547 usbo_hc_halt(husb, chnum);
1548 hc->state = USBO_HC_XACTERR;
1549#if 1 /* ROI DEBUG */
1550 syslog_1(LOG_NOTICE, "## SET USBO_HC_XACTERR2 [%08x] ##", sil_rew_mem((uint32_t *)(USBHC_BASE(base, chnum)+TOFF_USBHC_HCINT)));
1551#endif /* ROI DEBUG */
1552 clear_hc_int(base, chnum, USB_OTG_HCINT_TXERR);
1553 }
1554 else if(hc_int_status(base, chnum, USB_OTG_HCINT_DTERR) != 0){
1555 sil_orw_mem((uint32_t *)(USBHC_BASE(base, chnum)+TOFF_USBHC_HCINTMSK), USB_OTG_HCINTMSK_CHHM);
1556 usbo_hc_halt(husb, chnum);
1557 clear_hc_int(base, chnum, USB_OTG_HCINT_NAK);
1558 clear_hc_int(base, chnum, USB_OTG_HCINT_DTERR);
1559 hc->state = USBO_HC_DATATGLERR;
1560 }
1561 else if(hc_int_status(base, chnum, USB_OTG_HCINT_CHH) != 0){
1562 sil_andw_mem((uint32_t *)(USBHC_BASE(base, chnum)+TOFF_USBHC_HCINTMSK), USB_OTG_HCINTMSK_CHHM);
1563 if(hc->state == USBO_HC_XFRC){
1564 hc->urb_state = URB_DONE;
1565 if(hc->ep_type == EP_TYPE_BULK){
1566 hc->toggle_out ^= 1U;
1567 }
1568 }
1569 else if (hc->state == USBO_HC_NAK){
1570 hc->urb_state = URB_NOTREADY;
1571 }
1572 else if (hc->state == USBO_HC_NYET){
1573 hc->urb_state = URB_NOTREADY;
1574 hc->do_ping = 0U;
1575 }
1576 else if (hc->state == USBO_HC_STALL){
1577 hc->urb_state = URB_STALL;
1578 }
1579 else if((hc->state == USBO_HC_XACTERR) || (hc->state == USBO_HC_DATATGLERR)){
1580 if(hc->err_count++ > 3){
1581 hc->err_count = 0;
1582 hc->urb_state = URB_ERROR;
1583 }
1584 else{
1585 hc->urb_state = URB_NOTREADY;
1586 }
1587
1588 /* re-activate the channel */
1589 sil_modw_mem((uint32_t *)(USBHC_BASE(base, chnum)+TOFF_USBHC_HCCHAR), USB_OTG_HCCHAR_CHDIS, USB_OTG_HCCHAR_CHENA);
1590 }
1591 clear_hc_int(base, chnum, USB_OTG_HCINT_CHH);
1592 if(husb->hostchangeurbcallback != NULL)
1593 husb->hostchangeurbcallback(husb, chnum, husb->hc[chnum].urb_state);
1594 }
1595}
1596
1597/*
1598 * RX QUEUE LEVEL割込み要求
1599 * parameter1 husb USBハンドラへのポインタ
1600 */
1601static void
1602usbo_rxqlvl_irqhandler(USB_OTG_Handle_t *husb)
1603{
1604 uint32_t base = husb->base;
1605 uint8_t channelnum = 0U;
1606 uint32_t pktsts, pktcnt;
1607 uint32_t temp = 0U;
1608
1609 temp = sil_rew_mem((uint32_t *)(USBOTG_BASE(base)+TOFF_USBO_GRXSTSP));
1610 channelnum = temp & USB_OTG_GRXSTSP_EPNUM;
1611 pktsts = (temp & USB_OTG_GRXSTSP_PKTSTS) >> 17U;
1612 pktcnt = (temp & USB_OTG_GRXSTSP_BCNT) >> 4U;
1613
1614 switch(pktsts){
1615 case GRXSTS_PKTSTS_IN:
1616 /*
1617 * HOSTバッファパケット読み込み
1618 */
1619 if((pktcnt > 0) && (husb->hc[channelnum].xfer_buff != (void *)0U)){
1620 usbo_readPacket(husb->base, husb->hc[channelnum].xfer_buff, pktcnt);
1621
1622 /*
1623 * マルチデータ処理
1624 */
1625 husb->hc[channelnum].xfer_buff += pktcnt;
1626 husb->hc[channelnum].xfer_count += pktcnt;
1627
1628 if((sil_rew_mem((uint32_t *)(USBHC_BASE(base, channelnum)+TOFF_USBHC_HCTSIZ)) & USB_OTG_HCTSIZ_PKTCNT) > 0){
1629 sil_modw_mem((uint32_t *)(USBHC_BASE(base, channelnum)+TOFF_USBHC_HCCHAR), USB_OTG_HCCHAR_CHDIS, USB_OTG_HCCHAR_CHENA);
1630 husb->hc[channelnum].toggle_in ^= 1U;
1631 }
1632 }
1633 break;
1634
1635 case GRXSTS_PKTSTS_DATA_TOGGLE_ERR:
1636 case GRXSTS_PKTSTS_IN_XFER_COMP:
1637 case GRXSTS_PKTSTS_CH_HALTED:
1638 default:
1639 break;
1640 }
1641}
1642
1643/*
1644 * HOSTポート割込み要求
1645 * parameter1 husb USBハンドラへのポインタ
1646 */
1647static void
1648usbo_port_irqhandler(USB_OTG_Handle_t *husb)
1649{
1650 uint32_t base = husb->base;
1651 volatile uint32_t hprt0, hprt0_dup;
1652
1653 hprt0 = sil_rew_mem((uint32_t*)(USBPRT_BASE(base)));
1654 hprt0_dup = hprt0 & ~USB_OTG_HPRT_PENA;
1655
1656 /*
1657 * ポートコネクトチェック
1658 */
1659 if((hprt0 & USB_OTG_HPRT_PCDET) != 0){
1660 if((hprt0 & USB_OTG_HPRT_PCSTS) == USB_OTG_HPRT_PCSTS){
1661 sil_andw_mem((uint32_t *)(USBOTG_BASE(base)+TOFF_USBO_GINTMSK), USB_OTG_GINTSTS_DISCINT);
1662 if(husb->hostconnectcallback != NULL)
1663 husb->hostconnectcallback(husb);
1664 }
1665 }
1666
1667 /*
1668 * ポートイネーブル変化チェック
1669 */
1670 if((hprt0 & USB_OTG_HPRT_PENCHNG) != 0){
1671 if((hprt0 & USB_OTG_HPRT_PENA) != 0){
1672 if(husb->Init.phy_itface == USB_PHY_EMBEDDED){
1673 if((hprt0 & USB_OTG_HPRT_PSPD) == (HPRT0_PRTSPD_LOW_SPEED << 17)){
1674 usbo_initFSLSPClkSel(husb, 6000);
1675 }
1676 else{
1677 usbo_initFSLSPClkSel(husb, 48000);
1678 }
1679 }
1680 else{
1681 if(husb->Init.speed == USB_SPEED_FULL){
1682 sil_wrw_mem((uint32_t *)(USBH_BASE(base)+TOFF_USBH_HFIR), 60000U);
1683 }
1684 }
1685
1686 if(husb->hostconnectcallback != NULL)
1687 husb->hostconnectcallback(husb);
1688
1689 if(husb->Init.speed == USB_SPEED_HIGH){
1690 sil_orw_mem((uint32_t *)(USBOTG_BASE(base)+TOFF_USBO_GINTMSK), USB_OTG_GINTSTS_DISCINT);
1691 }
1692 }
1693 else{
1694 /*
1695 * HPRTのクリーン
1696 */
1697 sil_andw_mem((uint32_t*)(USBPRT_BASE(base)), (USB_OTG_HPRT_PENA | USB_OTG_HPRT_PCDET |\
1698 USB_OTG_HPRT_PENCHNG | USB_OTG_HPRT_POCCHNG ));
1699 sil_orw_mem((uint32_t *)(USBOTG_BASE(base)+TOFF_USBO_GINTMSK), USB_OTG_GINTSTS_DISCINT);
1700 }
1701 }
1702
1703 /*
1704 * ポート割込みクリア
1705 */
1706 sil_wrw_mem((uint32_t*)(USBPRT_BASE(base)), hprt0_dup);
1707}
1708
1709/*
1710 * HOST割込みハンドラ
1711 * parameter1 husb USBハンドラへのポインタ
1712 */
1713void
1714usbo_hcd_irqhandler(USB_OTG_Handle_t *husb)
1715{
1716 uint32_t base = husb->base;
1717 uint32_t msk = sil_rew_mem((uint32_t *)(USBOTG_BASE(base)+TOFF_USBO_GINTMSK));
1718 uint32_t i = 0, int_status = 0, intsts = 0;
1719
1720 /*
1721 * 許可しない要因の割込みは無視する
1722 */
1723 if((intsts = get_int_status(base, msk)) == 0){
1724 intsts = sil_rew_mem((uint32_t *)(USBOTG_BASE(base)+TOFF_USBO_GINTSTS));
1725 syslog_1(LOG_EMERG, "usbo_hcd_irqhandler Error Intrrupt[%08x] !", intsts);
1726 clear_host_int(base, intsts);
1727 return;
1728 }
1729
1730 if((intsts & USB_OTG_GINTSTS_PXFR_INCOMPISOOUT) != 0){
1731 /*
1732 * 未要求割込み要因クリア
1733 */
1734 clear_host_int(base, USB_OTG_GINTSTS_PXFR_INCOMPISOOUT);
1735 }
1736 if((intsts & USB_OTG_GINTSTS_IISOIXFR) != 0){
1737 /*
1738 * 未要求割込み要因クリア
1739 */
1740 clear_host_int(base, USB_OTG_GINTSTS_IISOIXFR);
1741 }
1742
1743 if((intsts & USB_OTG_GINTSTS_PTXFE) != 0){
1744 /*
1745 * 未要求割込み要因クリア
1746 */
1747 clear_host_int(base, USB_OTG_GINTSTS_PTXFE);
1748 }
1749 if((intsts & USB_OTG_GINTSTS_MMIS) != 0){
1750 /*
1751 * 未要求割込み要因クリア
1752 */
1753 clear_host_int(base, USB_OTG_GINTSTS_MMIS);
1754 }
1755 /*
1756 * HOSTディスコネクト割込み
1757 */
1758 if((intsts & USB_OTG_GINTSTS_DISCINT) != 0){
1759 /*
1760 * HPRTのクリーンアップ
1761 */
1762 sil_andw_mem((uint32_t*)(USBPRT_BASE(base)), (USB_OTG_HPRT_PENA | USB_OTG_HPRT_PCDET |\
1763 USB_OTG_HPRT_PENCHNG | USB_OTG_HPRT_POCCHNG ));
1764 if(husb->hostdisconnectcallback != NULL)
1765 husb->hostdisconnectcallback(husb);
1766 usbo_initFSLSPClkSel(husb, 48000);
1767 clear_host_int(base, USB_OTG_GINTSTS_DISCINT);
1768 }
1769 /*
1770 * HOSTポート割込み
1771 */
1772 if((intsts & USB_OTG_GINTSTS_HPRTINT) != 0){
1773 syslog_0(LOG_NOTICE, "## usbo_hcd_irqhandler USB_OTG_GINTSTS_HPRTINT ##");
1774 usbo_port_irqhandler(husb);
1775 if(husb->Init.usb_otg_mode == USB_OTG_MODE_DRD)
1776 sil_dly_nse(10*1000*1000); /* 注意:デバイスレディまでの待ち(割込みでしか待てない) */
1777 }
1778 /*
1779 * Host SOF割込み
1780 */
1781 if((intsts & USB_OTG_GINTSTS_SOF) != 0){
1782 if(husb->hostsofcallback != NULL)
1783 husb->hostsofcallback(husb);
1784 clear_host_int(base, USB_OTG_GINTSTS_SOF);
1785 }
1786 /*
1787 * HOSTチャネル割込み
1788 */
1789 if((intsts & USB_OTG_GINTSTS_HCINT) != 0){
1790 int_status = get_haint_status(base);
1791 for(i = 0 ; i < husb->Init.host_channels; i++){
1792 if(int_status & (1 << i)){
1793 if((sil_rew_mem((uint32_t *)(USBHC_BASE(husb->base, i)+TOFF_USBHC_HCCHAR)) & USB_OTG_HCCHAR_EPDIR) != 0)
1794 usbo_hc_in_irqhandler(husb, i);
1795 else
1796 usbo_hc_out_irqhandler(husb, i);
1797 }
1798 }
1799 clear_host_int(base, USB_OTG_GINTSTS_HCINT);
1800 }
1801 /*
1802 * RXキューレベル割込み
1803 */
1804 if((intsts & USB_OTG_GINTSTS_RXFLVL) != 0){
1805 sil_andw_mem((uint32_t *)(USBOTG_BASE(base)+TOFF_USBO_GINTMSK), USB_OTG_GINTSTS_RXFLVL);
1806 usbo_rxqlvl_irqhandler(husb);
1807 sil_orw_mem((uint32_t *)(USBOTG_BASE(base)+TOFF_USBO_GINTMSK), USB_OTG_GINTSTS_RXFLVL);
1808 }
1809}
1810
1811/*******************************************************************************
1812 USB DEVICE関数
1813*******************************************************************************/
1814/*
1815 * USB DEVICEスピード設定
1816 * parameter1 base USB OTGレジスタベースアドレス
1817 * parameter2 speed device speed USB_SPEED_HIGH(High speed mode)
1818 * USB_SPEED_HIGH_IN_FULL(High speed core in Full Speed mode)
1819 * USB_SPEED_FULL(Full speed mode)
1820 * USB_SPEED_LOW(Low speed mode)
1821 */
1822static void
1823usbo_setDevSpeed(uint32_t base, uint8_t speed)
1824{
1825 sil_orw_mem((uint32_t *)(USBD_BASE(base)+TOFF_USBD_DCFG), speed);
1826}
1827
1828/*
1829 * デバイスコネクト
1830 * parameter1 husb USBハンドラへのポインタ
1831 * return 常にE_OK
1832 */
1833ER
1834usbo_devconnect(USB_OTG_Handle_t *husb)
1835{
1836 sil_andw_mem((uint32_t *)(USBD_BASE(husb->base)+TOFF_USBD_DCTL), USB_OTG_DCTL_SDIS);
1837// dly_tsk(3);
1838 return E_OK;
1839}
1840
1841/*
1842 * デバイスディスコネクト
1843 * parameter1 husb USBハンドラへのポインタ
1844 * return 常にE_OK
1845 */
1846ER
1847usbo_devdisconnect(USB_OTG_Handle_t *husb)
1848{
1849 sil_orw_mem((uint32_t *)(USBD_BASE(husb->base)+TOFF_USBD_DCTL), USB_OTG_DCTL_SDIS);
1850// dly_tsk(3);
1851 return E_OK;
1852}
1853
1854/*
1855 * アクティブエンドポイント設定
1856 * parameter1 husb USBハンドラへのポインタ
1857 * parameter2 ep エンドポイント構造体へのポインタ
1858 * return 常にE_OK
1859 */
1860ER
1861usbo_activateEndpoint(USB_OTG_Handle_t *husb, USB_OTG_EPTypeDef *ep)
1862{
1863 uint32_t base = husb->base;
1864
1865 if(ep->is_in == 1){
1866 sil_orw_mem((uint32_t *)(USBD_BASE(base)+TOFF_USBD_DAINTMSK), USB_OTG_DAINTMSK_IEPM & (1 << (ep->num)));
1867 if(((sil_rew_mem((uint32_t *)(USBIEP_BASE(base, ep->num)+TOFF_USBEI_DIEPCTL))) & USB_OTG_DIEPCTL_USBAEP) == 0){
1868 sil_orw_mem((uint32_t *)(USBIEP_BASE(base, ep->num)+TOFF_USBEI_DIEPCTL), ((ep->maxpacket & USB_OTG_DIEPCTL_MPSIZ ) | (ep->type << 18U) |\
1869 ((ep->num) << 22U) | (USB_OTG_DIEPCTL_SD0PID_SEVNFRM) | (USB_OTG_DIEPCTL_USBAEP)));
1870 }
1871 }
1872 else{
1873 sil_orw_mem((uint32_t *)(USBD_BASE(base)+TOFF_USBD_DAINTMSK), USB_OTG_DAINTMSK_OEPM & ((1 << (ep->num)) << 16));
1874 if(((sil_rew_mem((uint32_t *)(USBOEP_BASE(base, ep->num)+TOFF_USBEO_DOEPCTL))) & USB_OTG_DIEPCTL_USBAEP) == 0){
1875 sil_orw_mem((uint32_t *)(USBOEP_BASE(base, ep->num)+TOFF_USBEO_DOEPCTL), ((ep->maxpacket & USB_OTG_DOEPCTL_MPSIZ ) | (ep->type << 18U) |\
1876 (USB_OTG_DIEPCTL_SD0PID_SEVNFRM)| (USB_OTG_DOEPCTL_USBAEP)));
1877 }
1878 }
1879 return E_OK;
1880}
1881
1882/*
1883 * ディスアクティブエンドポイント設定
1884 * parameter1 husb USBハンドラへのポインタ
1885 * parameter2 ep エンドポイント構造体へのポインタ
1886 * return 常にE_OK
1887 */
1888ER
1889usbo_deactivateEndpoint(USB_OTG_Handle_t *husb, USB_OTG_EPTypeDef *ep)
1890{
1891 uint32_t base = husb->base;
1892
1893 if(ep->is_in == 1){
1894 sil_andw_mem((uint32_t *)(USBD_BASE(base)+TOFF_USBD_DEACHMSK), (USB_OTG_DAINTMSK_IEPM & (1 << (ep->num))));
1895 sil_andw_mem((uint32_t *)(USBD_BASE(base)+TOFF_USBD_DAINTMSK), (USB_OTG_DAINTMSK_IEPM & (1 << (ep->num))));
1896 sil_andw_mem((uint32_t *)(USBIEP_BASE(base, ep->num)+TOFF_USBEI_DIEPCTL), USB_OTG_DIEPCTL_USBAEP);
1897 }
1898 else{
1899 sil_andw_mem((uint32_t *)(USBD_BASE(base)+TOFF_USBD_DEACHMSK), (USB_OTG_DAINTMSK_OEPM & ((1 << (ep->num)) << 16)));
1900 sil_andw_mem((uint32_t *)(USBD_BASE(base)+TOFF_USBD_DAINTMSK), (USB_OTG_DAINTMSK_OEPM & ((1 << (ep->num)) << 16)));
1901 sil_andw_mem((uint32_t *)(USBOEP_BASE(base, ep->num)+TOFF_USBEO_DOEPCTL), USB_OTG_DOEPCTL_USBAEP);
1902 }
1903 return E_OK;
1904}
1905
1906/*
1907 * エンドポイントにステール状態を設定
1908 * parameter1 husb USBハンドラへのポインタ
1909 * parameter2 ep エンドポイント構造体へのポインタ
1910 * return 常にE_OK
1911 */
1912ER
1913usbo_epsetStall(USB_OTG_Handle_t *husb, USB_OTG_EPTypeDef *ep)
1914{
1915 uint32_t base = husb->base;
1916
1917 if(ep->is_in == 1){
1918 if((sil_rew_mem((uint32_t *)(USBIEP_BASE(base, ep->num)+TOFF_USBEI_DIEPCTL)) & USB_OTG_DIEPCTL_EPENA) == 0){
1919 sil_andw_mem((uint32_t *)(USBIEP_BASE(base, ep->num)+TOFF_USBEI_DIEPCTL), USB_OTG_DIEPCTL_EPDIS);
1920 }
1921 sil_orw_mem((uint32_t *)(USBIEP_BASE(base, ep->num)+TOFF_USBEI_DIEPCTL), USB_OTG_DIEPCTL_STALL);
1922 }
1923 else{
1924 if((sil_rew_mem((uint32_t *)(USBOEP_BASE(base, ep->num)+TOFF_USBEO_DOEPCTL)) & USB_OTG_DOEPCTL_EPENA) == 0){
1925 sil_andw_mem((uint32_t *)(USBOEP_BASE(base, ep->num)+TOFF_USBEO_DOEPCTL), USB_OTG_DOEPCTL_EPDIS);
1926 }
1927 sil_orw_mem((uint32_t *)(USBOEP_BASE(base, ep->num)+TOFF_USBEO_DOEPCTL), USB_OTG_DOEPCTL_STALL);
1928 }
1929 return E_OK;
1930}
1931
1932/*
1933 * エンドポイントのステール状態をクリア
1934 * parameter1 husb USBハンドラへのポインタ
1935 * parameter2 ep エンドポイント構造体へのポインタ
1936 * return 常にE_OK
1937 *
1938 */
1939ER
1940usbo_epclearStall(USB_OTG_Handle_t *husb, USB_OTG_EPTypeDef *ep)
1941{
1942 uint32_t base = husb->base;
1943
1944 if(ep->is_in == 1){
1945 sil_andw_mem((uint32_t *)(USBIEP_BASE(base, ep->num)+TOFF_USBEI_DIEPCTL), USB_OTG_DIEPCTL_STALL);
1946 if(ep->type == EP_TYPE_INTR || ep->type == EP_TYPE_BULK){
1947 sil_orw_mem((uint32_t *)(USBIEP_BASE(base, ep->num)+TOFF_USBEI_DIEPCTL), USB_OTG_DIEPCTL_SD0PID_SEVNFRM); /* DATA0 */
1948 }
1949 }
1950 else{
1951 sil_andw_mem((uint32_t *)(USBOEP_BASE(base, ep->num)+TOFF_USBEO_DOEPCTL), USB_OTG_DOEPCTL_STALL);
1952 if(ep->type == EP_TYPE_INTR || ep->type == EP_TYPE_BULK){
1953 sil_orw_mem((uint32_t *)(USBOEP_BASE(base, ep->num)+TOFF_USBEO_DOEPCTL), USB_OTG_DOEPCTL_SD0PID_SEVNFRM); /* DATA0 */
1954 }
1955 }
1956 return E_OK;
1957}
1958
1959/**
1960 * USBにデバイスアドレスを設定
1961 * parameter1 husb USBハンドラへのポインタ
1962 * parameter2 addree デバイスアドレス(0-255)
1963 * return 常にE_OK
1964 */
1965ER
1966usbo_setDevAddress(USB_OTG_Handle_t *husb, uint8_t address)
1967{
1968 husb->connected = 1;
1969 sil_andw_mem((uint32_t *)(USBD_BASE(husb->base)+TOFF_USBD_DCFG), USB_OTG_DCFG_DAD);
1970 sil_orw_mem((uint32_t *)(USBD_BASE(husb->base)+TOFF_USBD_DCFG), ((address << 4) & USB_OTG_DCFG_DAD));
1971 return E_OK;
1972}
1973
1974/*
1975 * USBデバイススピードを取り出す
1976 * parameter1 husb USBハンドラへのポインタ
1977 * return speed デバイススピード USB_SPEED_HIGH: High speed mode
1978 * USB_SPEED_FULL: Full speed mode
1979 * USB_SPEED_LOW: Low speed mode
1980 */
1981uint8_t
1982usbo_getDevSpeed(USB_OTG_Handle_t *husb)
1983{
1984 uint8_t speed = 0;
1985 uint32_t status = sil_rew_mem((uint32_t *)(USBD_BASE(husb->base)+TOFF_USBD_DSTS));
1986
1987 if((status & USB_OTG_DSTS_ENUMSPD) == DSTS_ENUMSPD_HS_PHY_30MHZ_OR_60MHZ){
1988 speed = USB_SPEED_HIGH;
1989 }
1990 else if(((status & USB_OTG_DSTS_ENUMSPD) == DSTS_ENUMSPD_FS_PHY_30MHZ_OR_60MHZ) || ((status & USB_OTG_DSTS_ENUMSPD) == DSTS_ENUMSPD_FS_PHY_48MHZ)){
1991 speed = USB_SPEED_FULL;
1992 }
1993 else if((status & USB_OTG_DSTS_ENUMSPD) == DSTS_ENUMSPD_LS_PHY_6MHZ){
1994 speed = USB_SPEED_LOW;
1995 }
1996 return speed;
1997}
1998
1999/*
2000 * EP0-OUTスタート
2001 * parameter1 husb USBハンドラへのポインタ
2002 * parameter2 psetup セットアップパケットデータへのポインタ
2003 * return 常にE_OK
2004 */
2005ER
2006usbo_ep0_outstart(USB_OTG_Handle_t *husb, uint8_t *psetup)
2007{
2008 uint32_t base = husb->base;
2009
2010 sil_wrw_mem((uint32_t *)(USBOEP_BASE(base, 0)+TOFF_USBEO_DOEPTSIZ), 0);
2011 sil_orw_mem((uint32_t *)(USBOEP_BASE(base, 0)+TOFF_USBEO_DOEPTSIZ), (USB_OTG_DOEPTSIZ_PKTCNT & (1U << 19U)));
2012 sil_orw_mem((uint32_t *)(USBOEP_BASE(base, 0)+TOFF_USBEO_DOEPTSIZ), (3U * 8U));
2013 sil_orw_mem((uint32_t *)(USBOEP_BASE(base, 0)+TOFF_USBEO_DOEPTSIZ), USB_OTG_DOEPTSIZ_STUPCNT);
2014
2015 if(husb->Init.dma_enable == 1){
2016 flushinvalidatedcache_by_addr(psetup, 64);
2017 sil_wrw_mem((uint32_t *)(USBOEP_BASE(base, 0)+TOFF_USBEO_DOEPDMA), (uint32_t)psetup);
2018 /*
2019 * EP0有効化
2020 */
2021 sil_wrw_mem((uint32_t *)(USBOEP_BASE(base, 0)+TOFF_USBEO_DOEPCTL), 0x80008000);
2022 }
2023 return E_OK;
2024}
2025
2026/*
2027 * EP0転送スタート
2028 * parameter1 husb USBハンドラへのポインタ
2029 * parameter2 ep エンドポイント構造体へのポインタ
2030 * return 常にE_OK
2031 */
2032ER
2033usbo_ep0startxfer(USB_OTG_Handle_t *husb, USB_OTG_EPTypeDef *ep)
2034{
2035 uint32_t base = husb->base;
2036 uint8_t epnum = ep->num;
2037
2038 if(ep->is_in == 1){ /* INエンドポイント */
2039 if(ep->xfer_len == 0){ /* ZERO-LENGTHパケット */
2040 sil_andw_mem((uint32_t *)(USBIEP_BASE(base, epnum)+TOFF_USBEI_DIEPTSIZ), USB_OTG_DIEPTSIZ_PKTCNT);
2041 sil_orw_mem((uint32_t *)(USBIEP_BASE(base, epnum)+TOFF_USBEI_DIEPTSIZ), (USB_OTG_DIEPTSIZ_PKTCNT & (1 << 19)));
2042 sil_andw_mem((uint32_t *)(USBIEP_BASE(base, epnum)+TOFF_USBEI_DIEPTSIZ), USB_OTG_DIEPTSIZ_XFRSIZ);
2043 }
2044 else{ /* 通常パケット */
2045 /*
2046 * パケット数とデータ長に分けて設定(EP0なのでパケット数は1)
2047 */
2048 sil_andw_mem((uint32_t *)(USBIEP_BASE(base, epnum)+TOFF_USBEI_DIEPTSIZ), USB_OTG_DIEPTSIZ_XFRSIZ);
2049 sil_andw_mem((uint32_t *)(USBIEP_BASE(base, epnum)+TOFF_USBEI_DIEPTSIZ), USB_OTG_DIEPTSIZ_PKTCNT);
2050 if(ep->xfer_len > ep->maxpacket){
2051 ep->xfer_len = ep->maxpacket;
2052 }
2053 sil_orw_mem((uint32_t *)(USBIEP_BASE(base, epnum)+TOFF_USBEI_DIEPTSIZ), (USB_OTG_DIEPTSIZ_PKTCNT & (1 << 19)));
2054 sil_orw_mem((uint32_t *)(USBIEP_BASE(base, epnum)+TOFF_USBEI_DIEPTSIZ), (USB_OTG_DIEPTSIZ_XFRSIZ & ep->xfer_len));
2055 }
2056
2057 if(husb->Init.dma_enable == 1){
2058 flushinvalidatedcache_by_addr(((uint8_t *)ep->dma_addr), ep->xfer_len);
2059 sil_wrw_mem((uint32_t *)(USBIEP_BASE(base, epnum)+TOFF_USBEI_DIEPDMA), ep->dma_addr);
2060 }
2061 else{
2062 /*
2063 * DMAモードでない場合は、EMPTY割込みを設定
2064 */
2065 if(ep->xfer_len > 0){
2066 sil_orw_mem((uint32_t *)(USBD_BASE(base)+TOFF_USBD_DIEPEMPMSK), (1 << (ep->num)));
2067 }
2068 }
2069 /*
2070 * クリアNAK、エンドポイントイネーブル
2071 */
2072 sil_orw_mem((uint32_t *)(USBIEP_BASE(base, epnum)+TOFF_USBEI_DIEPCTL), (USB_OTG_DIEPCTL_CNAK | USB_OTG_DIEPCTL_EPENA));
2073 }
2074 else{ /* OUTエンドポイント */
2075 /*
2076 * パケット数とデータ長に分けて設定(EP0なのでパケット数は1)
2077 */
2078 sil_andw_mem((uint32_t *)(USBOEP_BASE(base, epnum)+TOFF_USBEO_DOEPTSIZ), USB_OTG_DOEPTSIZ_XFRSIZ);
2079 sil_andw_mem((uint32_t *)(USBOEP_BASE(base, epnum)+TOFF_USBEO_DOEPTSIZ), USB_OTG_DOEPTSIZ_PKTCNT);
2080
2081 if(ep->xfer_len > 0U){
2082 ep->xfer_len = ep->maxpacket;
2083 }
2084
2085 sil_orw_mem((uint32_t *)(USBOEP_BASE(base, epnum)+TOFF_USBEO_DOEPTSIZ), (USB_OTG_DOEPTSIZ_PKTCNT & (1 << 19)));
2086 sil_orw_mem((uint32_t *)(USBOEP_BASE(base, epnum)+TOFF_USBEO_DOEPTSIZ), (USB_OTG_DOEPTSIZ_XFRSIZ & (ep->maxpacket)));
2087
2088 if(husb->Init.dma_enable == 1){
2089 flushinvalidatedcache_by_addr(ep->xfer_buff, ep->xfer_len);
2090 sil_wrw_mem((uint32_t *)(USBOEP_BASE(base, epnum)+TOFF_USBEO_DOEPDMA), (uint32_t)(ep->xfer_buff));
2091 }
2092 /*
2093 * クリアNAK、エンドポイントイネーブル
2094 */
2095 sil_orw_mem((uint32_t *)(USBOEP_BASE(base, epnum)+TOFF_USBEO_DOEPCTL), (USB_OTG_DOEPCTL_CNAK | USB_OTG_DOEPCTL_EPENA));
2096 }
2097 return E_OK;
2098}
2099
2100/*
2101 * EPn転送スタート
2102 * parameter1 husb USBハンドラへのポインタ
2103 * parameter2 ep エンドポイント構造体へのポインタ
2104 * return 常にE_OK
2105 */
2106ER
2107usbo_epstartxfer(USB_OTG_Handle_t *husb, USB_OTG_EPTypeDef *ep)
2108{
2109 uint32_t base = husb->base;
2110 uint16_t pktcnt = 0;
2111 uint8_t epnum = ep->num;
2112
2113 if(ep->is_in == 1){ /* INエンドポイント */
2114 if(ep->xfer_len == 0){ /* ZERO-LENGTHパケット */
2115 sil_andw_mem((uint32_t *)(USBIEP_BASE(base, epnum)+TOFF_USBEI_DIEPTSIZ), USB_OTG_DIEPTSIZ_PKTCNT);
2116 sil_orw_mem((uint32_t *)(USBIEP_BASE(base, epnum)+TOFF_USBEI_DIEPTSIZ), (USB_OTG_DIEPTSIZ_PKTCNT & (1 << 19)));
2117 sil_andw_mem((uint32_t *)(USBIEP_BASE(base, epnum)+TOFF_USBEI_DIEPTSIZ), USB_OTG_DIEPTSIZ_XFRSIZ);
2118 }
2119 else{ /* 通常パケット */
2120 /*
2121 * パケット数とデータ長に分けて設定
2122 */
2123 sil_andw_mem((uint32_t *)(USBIEP_BASE(base, epnum)+TOFF_USBEI_DIEPTSIZ), USB_OTG_DIEPTSIZ_XFRSIZ);
2124 sil_andw_mem((uint32_t *)(USBIEP_BASE(base, epnum)+TOFF_USBEI_DIEPTSIZ), USB_OTG_DIEPTSIZ_PKTCNT);
2125 sil_orw_mem((uint32_t *)(USBIEP_BASE(base, epnum)+TOFF_USBEI_DIEPTSIZ), (USB_OTG_DIEPTSIZ_PKTCNT & (((ep->xfer_len + ep->maxpacket -1)/ ep->maxpacket) << 19)));
2126 sil_orw_mem((uint32_t *)(USBIEP_BASE(base, epnum)+TOFF_USBEI_DIEPTSIZ), (USB_OTG_DIEPTSIZ_XFRSIZ & ep->xfer_len));
2127
2128 if(ep->type == EP_TYPE_ISOC){
2129 sil_andw_mem((uint32_t *)(USBIEP_BASE(base, epnum)+TOFF_USBEI_DIEPTSIZ), USB_OTG_DIEPTSIZ_MULCNT);
2130 sil_orw_mem((uint32_t *)(USBIEP_BASE(base, epnum)+TOFF_USBEI_DIEPTSIZ), (USB_OTG_DIEPTSIZ_MULCNT & (1 << 29)));
2131 }
2132 }
2133
2134 if(husb->Init.dma_enable == 1){
2135 flushinvalidatedcache_by_addr(((uint8_t *)ep->dma_addr), ep->xfer_len);
2136 sil_wrw_mem((uint32_t *)(USBIEP_BASE(base, epnum)+TOFF_USBEI_DIEPDMA), ep->dma_addr);
2137 }
2138 else{
2139 /*
2140 * EPがISOCでない場合、送信データありならばEMPTY割込みを設定
2141 */
2142 if(ep->type != EP_TYPE_ISOC && ep->xfer_len > 0){
2143 sil_orw_mem((uint32_t *)(USBD_BASE(base)+TOFF_USBD_DIEPEMPMSK), (1 << (epnum)));
2144 }
2145 }
2146
2147 if(ep->type == EP_TYPE_ISOC){
2148 if((sil_rew_mem((uint32_t *)(USBD_BASE(base)+TOFF_USBD_DSTS)) & (1 << 8)) == 0){
2149 sil_orw_mem((uint32_t *)(USBIEP_BASE(base, epnum)+TOFF_USBEI_DIEPCTL), USB_OTG_DIEPCTL_SODDFRM);
2150 }
2151 else{
2152 sil_orw_mem((uint32_t *)(USBIEP_BASE(base, epnum)+TOFF_USBEI_DIEPCTL), USB_OTG_DIEPCTL_SD0PID_SEVNFRM);
2153 }
2154 }
2155 /*
2156 * クリアNAK、エンドポイントイネーブル
2157 */
2158 sil_orw_mem((uint32_t *)(USBIEP_BASE(base, epnum)+TOFF_USBEI_DIEPCTL), (USB_OTG_DIEPCTL_CNAK | USB_OTG_DIEPCTL_EPENA));
2159
2160 if(ep->type == EP_TYPE_ISOC){
2161 usbo_writePacket(base, ep->xfer_buff, epnum, ep->xfer_len, husb->Init.dma_enable);
2162 }
2163 }
2164 else{ /* OUTエンドポイント */
2165 /*
2166 * パケット数とデータ長に分けて設定
2167 */
2168 sil_andw_mem((uint32_t *)(USBOEP_BASE(base, epnum)+TOFF_USBEO_DOEPTSIZ), USB_OTG_DOEPTSIZ_XFRSIZ);
2169 sil_andw_mem((uint32_t *)(USBOEP_BASE(base, epnum)+TOFF_USBEO_DOEPTSIZ), USB_OTG_DOEPTSIZ_PKTCNT);
2170
2171 if(ep->xfer_len == 0){ /* ZERO-LENGTHパケット */
2172 sil_orw_mem((uint32_t *)(USBOEP_BASE(base, epnum)+TOFF_USBEO_DOEPTSIZ), (USB_OTG_DOEPTSIZ_XFRSIZ & ep->maxpacket));
2173 sil_orw_mem((uint32_t *)(USBOEP_BASE(base, epnum)+TOFF_USBEO_DOEPTSIZ), (USB_OTG_DOEPTSIZ_PKTCNT & (1 << 19)));
2174 }
2175 else{ /* 通常パケット */
2176 pktcnt = (ep->xfer_len + ep->maxpacket - 1)/ ep->maxpacket;
2177 sil_orw_mem((uint32_t *)(USBOEP_BASE(base, epnum)+TOFF_USBEO_DOEPTSIZ), (USB_OTG_DOEPTSIZ_PKTCNT & (pktcnt << 19)));
2178 sil_orw_mem((uint32_t *)(USBOEP_BASE(base, epnum)+TOFF_USBEO_DOEPTSIZ), (USB_OTG_DOEPTSIZ_XFRSIZ & (ep->maxpacket * pktcnt)));
2179 }
2180
2181 if(husb->Init.dma_enable == 1){
2182 flushinvalidatedcache_by_addr(ep->xfer_buff, ep->xfer_len);
2183 sil_wrw_mem((uint32_t *)(USBOEP_BASE(base, epnum)+TOFF_USBEO_DOEPDMA), (uint32_t)(ep->xfer_buff));
2184 }
2185
2186 if(ep->type == EP_TYPE_ISOC){
2187 if((sil_rew_mem((uint32_t *)(USBD_BASE(base)+TOFF_USBD_DSTS)) & (1 << 8)) == 0){
2188 sil_orw_mem((uint32_t *)(USBOEP_BASE(base, epnum)+TOFF_USBEO_DOEPCTL), USB_OTG_DOEPCTL_SODDFRM);
2189 }
2190 else{
2191 sil_orw_mem((uint32_t *)(USBOEP_BASE(base, epnum)+TOFF_USBEO_DOEPCTL), USB_OTG_DOEPCTL_SD0PID_SEVNFRM);
2192 }
2193 }
2194 /*
2195 * クリアNAK、エンドポイントイネーブル
2196 */
2197 sil_orw_mem((uint32_t *)(USBOEP_BASE(base, epnum)+TOFF_USBEO_DOEPCTL), (USB_OTG_DOEPCTL_CNAK | USB_OTG_DOEPCTL_EPENA));
2198 }
2199 return E_OK;
2200}
2201
2202/*
2203 * USBデバイス初期化
2204 * parameter1 husb USBハンドラへのポインタ
2205 * return 常にE_OK
2206 */
2207ER
2208usbo_devinit(USB_OTG_Handle_t *husb)
2209{
2210 uint32_t base = husb->base;
2211 bool_t forced;
2212 uint32_t i = 0U;
2213
2214 /* Device mode configuration */
2215 sil_orw_mem((uint32_t *)(USBD_BASE(base)+TOFF_USBD_DCFG), DCFG_FRAME_INTERVAL_80);
2216
2217 if(husb->Init.phy_itface == USB_PHY_ULPI){ /* ULIP-PHY設定 */
2218 if(husb->Init.speed == USB_SPEED_HIGH){
2219 /*
2220 * ハイスピード固定
2221 */
2222 usbo_setDevSpeed(base, USB_SPEED_HIGH);
2223 }
2224 else{
2225 /*
2226 * ハイ・フル選択モード
2227 */
2228 usbo_setDevSpeed(base, USB_SPEED_HIGH_IN_FULL);
2229 }
2230 }
2231 else{ /* EMBEDDED-PHY設定 */
2232 /*
2233 * 常にフルスピード
2234 */
2235 usbo_setDevSpeed(base, USB_SPEED_FULL);
2236 }
2237
2238 /*
2239 * デバイスに関係する、すべての割込みをクリアする
2240 */
2241 sil_wrw_mem((uint32_t *)(USBD_BASE(base)+TOFF_USBD_DIEPMSK),
2242 (USB_OTG_DIEPMSK_TOM | USB_OTG_DIEPMSK_EPDM | USB_OTG_DIEPMSK_XFRCM));
2243 sil_wrw_mem((uint32_t *)(USBD_BASE(base)+TOFF_USBD_DOEPMSK),
2244 (USB_OTG_DOEPMSK_STUPM | USB_OTG_DOEPMSK_EPDM | USB_OTG_DOEPMSK_XFRCM));
2245 sil_wrw_mem((uint32_t *)(USBD_BASE(base)+TOFF_USBD_DAINT), 0xFFFFFFFF);
2246 sil_wrw_mem((uint32_t *)(USBD_BASE(base)+TOFF_USBD_DAINTMSK), 0);
2247 for(i = 0 ; i < husb->Init.dev_endpoints ; i++){
2248 if((sil_rew_mem((uint32_t *)(USBIEP_BASE(base, i)+TOFF_USBEI_DIEPCTL)) & USB_OTG_DIEPCTL_EPENA) != 0){
2249 sil_wrw_mem((uint32_t *)(USBIEP_BASE(base, i)+TOFF_USBEI_DIEPCTL), (USB_OTG_DIEPCTL_EPDIS | USB_OTG_DIEPCTL_SNAK));
2250 }
2251 else{
2252 sil_wrw_mem((uint32_t *)(USBIEP_BASE(base, i)+TOFF_USBEI_DIEPCTL), 0);
2253 }
2254 sil_wrw_mem((uint32_t *)(USBIEP_BASE(base, i)+TOFF_USBEI_DIEPTSIZ), 0);
2255 sil_wrw_mem((uint32_t *)(USBIEP_BASE(base, i)+TOFF_USBEI_DIEPINT), 0xFF);
2256 }
2257
2258 for (i = 0U; i < husb->Init.dev_endpoints; i++){
2259 if((sil_rew_mem((uint32_t *)(USBOEP_BASE(base, i)+TOFF_USBEO_DOEPCTL)) & USB_OTG_DOEPCTL_EPENA) != 0){
2260 sil_wrw_mem((uint32_t *)(USBOEP_BASE(base, i)+TOFF_USBEO_DOEPCTL), (USB_OTG_DOEPCTL_EPDIS | USB_OTG_DOEPCTL_SNAK));
2261 }
2262 else{
2263 sil_wrw_mem((uint32_t *)(USBOEP_BASE(base, i)+TOFF_USBEO_DOEPCTL), 0);
2264 }
2265 sil_wrw_mem((uint32_t *)(USBOEP_BASE(base, i)+TOFF_USBEO_DOEPTSIZ), 0);
2266 sil_wrw_mem((uint32_t *)(USBOEP_BASE(base, i)+TOFF_USBEO_DOEPINT), 0xFF);
2267 }
2268
2269 usbo_devdisconnect(husb);
2270 forced = usbo_force_mode_if_needed(husb, false);
2271 usbo_initFiFo(husb);
2272 if(forced)
2273 usbo_clear_force_mode(husb);
2274
2275 if(husb->Init.dma_enable == 1){
2276 /*
2277 * DMAモードならスレッシュホールドパラメータを設定
2278 */
2279 sil_wrw_mem((uint32_t *)(USBD_BASE(base)+TOFF_USBD_DTHRCTL), (USB_OTG_DTHRCTL_TXTHRLEN_6 | USB_OTG_DTHRCTL_RXTHRLEN_6));
2280 sil_orw_mem((uint32_t *)(USBD_BASE(base)+TOFF_USBD_DTHRCTL), (USB_OTG_DTHRCTL_RXTHREN | USB_OTG_DTHRCTL_ISOTHREN | USB_OTG_DTHRCTL_NONISOTHREN));
2281 i = sil_rew_mem((uint32_t *)(USBD_BASE(base)+TOFF_USBD_DTHRCTL));
2282 }
2283 if(husb->Init.usb_otg_mode == USB_OTG_MODE_DEVICE)
2284 usbo_setupint(husb);
2285 return E_OK;
2286}
2287
2288/*
2289 * USBデバイス停止
2290 * parameter1 husb USBハンドラへのポインタ
2291 * return 常にE_OK
2292 */
2293ER
2294usbo_stopdevice(USB_OTG_Handle_t *husb)
2295{
2296 uint32_t base = husb->base;
2297 uint32_t i;
2298
2299 /*
2300 * エンドポイントの割込みクリア
2301 */
2302 for(i = 0 ; i < 15 ; i++){
2303 sil_wrw_mem((uint32_t *)(USBIEP_BASE(base, i)+TOFF_USBEI_DIEPINT), 0xFF);
2304 sil_wrw_mem((uint32_t *)(USBOEP_BASE(base, i)+TOFF_USBEO_DOEPINT), 0xFF);
2305 }
2306 sil_wrw_mem((uint32_t *)(USBD_BASE(base)+TOFF_USBD_DAINT), 0xFFFFFFFF);
2307
2308 /*
2309 * エンドポイントの割込み設定
2310 */
2311 sil_wrw_mem((uint32_t *)(USBD_BASE(base)+TOFF_USBD_DIEPMSK), 0);
2312 sil_wrw_mem((uint32_t *)(USBD_BASE(base)+TOFF_USBD_DOEPMSK), 0);
2313 sil_wrw_mem((uint32_t *)(USBD_BASE(base)+TOFF_USBD_DAINTMSK), 0);
2314
2315 /*
2316 * FIFOフラッシュ
2317 */
2318 usbo_flushRxFifo(husb);
2319 usbo_flushTxFifo(husb, 0x10);
2320 return E_OK;
2321}
2322
2323/*
2324 * LPM初期設定
2325 */
2326ER
2327usbo_init_lpm(USB_OTG_Handle_t *husb)
2328{
2329#ifdef USB_OTG_GLPMCFG_LPMEN
2330 uint32_t base = husb->base;
2331
2332 if(husb->Init.lpm_enable == 1){
2333 husb->lpm_active = 1;
2334 husb->lpm_state = PCD_LPM_L0_ACTIVE;
2335 sil_orw_mem((uint32_t *)(USBOTG_BASE(base)+TOFF_USBO_GINTMSK), USB_OTG_GINTMSK_LPMINTM);
2336 sil_orw_mem((uint32_t *)(USBOTG_BASE(base)+TOFF_USBO_GLPMCFG), (USB_OTG_GLPMCFG_LPMEN | USB_OTG_GLPMCFG_LPMACK | USB_OTG_GLPMCFG_ENBESL));
2337 }
2338#endif /* USB_OTG_GLPMCFG_LPMEN */
2339 return E_OK;
2340}
2341
2342/*
2343 * USB EP-IN割込み要因取得
2344 * parameter1 base USB OTGレジスタベースアドレス
2345 * parameter2 epnum エンドポイント番号
2346 * return EP-IN割込み要因
2347 */
2348static uint32_t
2349usbo_devInEPInterrupt(uint32_t base , uint8_t epnum)
2350{
2351 uint32_t msk, emp;
2352
2353 msk = sil_rew_mem((uint32_t *)(USBD_BASE(base)+TOFF_USBD_DIEPMSK));
2354 emp = sil_rew_mem((uint32_t *)(USBD_BASE(base)+TOFF_USBD_DIEPEMPMSK));
2355 msk |= ((emp >> epnum) & 0x1) << 7;
2356 return sil_rew_mem((uint32_t *)(USBIEP_BASE(base, epnum)+TOFF_USBEI_DIEPINT)) & msk;
2357}
2358
2359/*
2360 * USB EP-OUT割込み要因取得
2361 * parameter1 base USB OTGレジスタベースアドレス
2362 * parameter2 epnum エンドポイント番号
2363 * return EP-OUT割込み要因
2364 */
2365static uint32_t
2366usbo_devOutEPInterrupt(uint32_t base, uint8_t epnum)
2367{
2368 uint32_t v;
2369 v = sil_rew_mem((uint32_t *)(USBOEP_BASE(base, epnum)+TOFF_USBEO_DOEPINT));
2370 return v & sil_rew_mem((uint32_t *)(USBD_BASE(base)+TOFF_USBD_DOEPMSK));
2371}
2372
2373
2374/*
2375 * 次のパケットを送信FIFOに設定
2376 * parameter1 husb USBハンドラへのポインタ
2377 * parameter2 epnum エンドポイント番号
2378 * return 常にE_OK
2379 */
2380static ER
2381usbo_writeemptyTxfifo(USB_OTG_Handle_t *husb, uint32_t epnum)
2382{
2383 uint32_t base = husb->base;
2384 USB_OTG_EPTypeDef *ep;
2385 int32_t len = 0U;
2386 uint32_t len32b;
2387
2388 ep = &husb->IN_ep[epnum];
2389 len = ep->xfer_len - ep->xfer_count;
2390
2391 if(len > ep->maxpacket){
2392 len = ep->maxpacket;
2393 }
2394 len32b = (len + 3) / 4;
2395
2396 while((sil_rew_mem((uint32_t *)(USBIEP_BASE(base, epnum)+TOFF_USBEI_DTXFSTS)) & USB_OTG_DTXFSTS_INEPTFSAV) > len32b
2397 && ep->xfer_count < ep->xfer_len && ep->xfer_len != 0){
2398 /*
2399 * 送信FIFOへのデータ書き込み
2400 */
2401 len = ep->xfer_len - ep->xfer_count;
2402 if(len > ep->maxpacket){
2403 len = ep->maxpacket;
2404 }
2405 len32b = (len + 3) / 4;
2406 usbo_writePacket(base, ep->xfer_buff, epnum, len, husb->Init.dma_enable);
2407 ep->xfer_buff += len;
2408 ep->xfer_count += len;
2409 }
2410
2411 if(len <= 0){ /* 最後のパケットならばEMPTY割込みをマスク */
2412 sil_andw_mem((uint32_t *)(USBD_BASE(base)+TOFF_USBD_DIEPEMPMSK), (1 << epnum));
2413 }
2414 return E_OK;
2415}
2416
2417/*
2418 * DEVICE割込みハンドラ
2419 * parameter1 husb USBハンドラへのポインタ
2420 */
2421void
2422usbo_pcd_irqhandler(USB_OTG_Handle_t *husb)
2423{
2424 USB_OTG_EPTypeDef *ep;
2425 uint32_t base = husb->base;
2426 uint32_t msk = sil_rew_mem((uint32_t *)(USBOTG_BASE(base)+TOFF_USBO_GINTMSK));
2427 uint32_t i = 0U, ep_intr = 0U, epint = 0U, epnum = 0U;
2428 uint32_t temp = 0;
2429
2430 /*
2431 * 割込みエラーチェック
2432 */
2433 if((get_int_status(base, msk) == 0)){
2434 uint32_t intsts = sil_rew_mem((uint32_t *)(USBOTG_BASE(base)+TOFF_USBO_GINTSTS));
2435 syslog_1(LOG_EMERG, "usbo_pcd_irqhandler Error Intrrupt[%08x] !", intsts);
2436 clear_dev_int(base, intsts);
2437 return;
2438 }
2439
2440 if((get_int_status(base, msk) & USB_OTG_GINTSTS_MMIS) != 0){
2441 /*
2442 * エラー割込み要因クリア
2443 */
2444 clear_dev_int(base, USB_OTG_GINTSTS_MMIS);
2445 }
2446 if((get_int_status(base, msk) & USB_OTG_GINTSTS_OEPINT) != 0){
2447 /*
2448 * EP-OUT割込み
2449 */
2450 ep_intr = get_outep_int_status(base);
2451 for(epnum = 0 ; epnum < 16 ; epnum++){
2452 if((ep_intr & (1<<epnum)) != 0){
2453 epint = usbo_devOutEPInterrupt(base, epnum);
2454 if((epint & USB_OTG_DOEPINT_XFRC) == USB_OTG_DOEPINT_XFRC){
2455 clear_outep_int(base, epnum, USB_OTG_DOEPINT_XFRC);
2456 if(husb->Init.dma_enable == 1U){
2457 husb->OUT_ep[epnum].xfer_count = husb->OUT_ep[epnum].maxpacket- (sil_rew_mem((uint32_t *)(USBOEP_BASE(base, epnum)+TOFF_USBEO_DOEPTSIZ)) & USB_OTG_DOEPTSIZ_XFRSIZ);
2458 husb->OUT_ep[epnum].xfer_buff += husb->OUT_ep[epnum].maxpacket;
2459 }
2460 if(husb->devdataoutstagecallback != NULL)
2461 husb->devdataoutstagecallback(husb, epnum);
2462 if(husb->Init.dma_enable == 1 && epnum == 0 && husb->OUT_ep[epnum].xfer_len == 0){
2463 /*
2464 * DMAモードEP0 ZERO LENGTHパケット送信
2465 */
2466 usbo_ep0_outstart(husb, (uint8_t *)husb->Setup);
2467 }
2468 }
2469 if((epint & USB_OTG_DOEPINT_STUP) != 0){
2470 /*
2471 * SETUPパケット通知
2472 */
2473 if(husb->devsetupstagecallback != NULL)
2474 husb->devsetupstagecallback(husb);
2475 clear_outep_int(base, epnum, USB_OTG_DOEPINT_STUP);
2476 }
2477 if((epint & USB_OTG_DOEPINT_OTEPDIS) != 0){
2478 clear_outep_int(base, epnum, USB_OTG_DOEPINT_OTEPDIS);
2479 }
2480#ifdef USB_OTG_DOEPINT_OTEPSPR
2481 /*
2482 * ステータスフェーズ受信割込み
2483 */
2484 if((epint & USB_OTG_DOEPINT_OTEPSPR) != 0){
2485 clear_outep_int(base, epnum, USB_OTG_DOEPINT_OTEPSPR);
2486 }
2487#endif /* USB_OTG_DOEPINT_OTEPSPR */
2488 }
2489 }
2490 }
2491 if((get_int_status(base, msk) & USB_OTG_GINTSTS_IEPINT) != 0){
2492 /*
2493 * EP-IN割込み
2494 */
2495 ep_intr = get_inep_int_status(base);
2496 for(epnum = 0 ; epnum < 16 ; epnum++){
2497 if((ep_intr & (1<<epnum)) != 0){ /* In ITR */
2498 epint = usbo_devInEPInterrupt(base, epnum);
2499 if((epint & USB_OTG_DIEPINT_XFRC) != 0){
2500 sil_andw_mem((uint32_t *)(USBD_BASE(base)+TOFF_USBD_DIEPEMPMSK), (1<<epnum));
2501 clear_inep_int(base, epnum, USB_OTG_DIEPINT_XFRC);
2502 if(husb->Init.dma_enable == 1){
2503 husb->IN_ep[epnum].xfer_buff += husb->IN_ep[epnum].maxpacket;
2504 }
2505 if(husb->devdatainstagecallback != NULL)
2506 husb->devdatainstagecallback(husb, epnum);
2507 if(husb->Init.dma_enable == 1 && epnum == 0 && husb->IN_ep[epnum].xfer_len == 0){
2508 /*
2509 * DMAモードEP0 ZERO LENGTHパケット送信
2510 */
2511 usbo_ep0_outstart(husb, (uint8_t *)husb->Setup);
2512 }
2513 }
2514 if((epint & USB_OTG_DIEPINT_TOC) != 0){
2515 clear_inep_int(base, epnum, USB_OTG_DIEPINT_TOC);
2516 }
2517 if((epint & USB_OTG_DIEPINT_ITTXFE) != 0){
2518 clear_inep_int(base, epnum, USB_OTG_DIEPINT_ITTXFE);
2519 }
2520 if((epint & USB_OTG_DIEPINT_INEPNE) != 0){
2521 clear_inep_int(base, epnum, USB_OTG_DIEPINT_INEPNE);
2522 }
2523 if((epint & USB_OTG_DIEPINT_EPDISD) != 0){
2524 clear_inep_int(base, epnum, USB_OTG_DIEPINT_EPDISD);
2525 }
2526 if((epint & USB_OTG_DIEPINT_TXFE) != 0){
2527 usbo_writeemptyTxfifo(husb , epnum);
2528 }
2529 }
2530 }
2531 }
2532 /*
2533 * RESUME割込み
2534 */
2535 if((get_int_status(base, msk) & USB_OTG_GINTSTS_WKUINT) != 0){
2536 usbo_exit_hibernation(husb, true); /* 省エネ復帰 */
2537#ifdef USB_OTG_GLPMCFG_LPMEN
2538 if(husb->lpm_state == PCD_LPM_L1_ACTIVE){
2539 husb->lpm_state = PCD_LPM_L0_ACTIVE;
2540 if(husb->devlpmcallback != NULL)
2541 husb->devlpmcallback(husb, PCD_LPM_L0_ACTIVE);
2542 }
2543 else
2544#endif /* USB_OTG_GLPMCFG_LPMEN */
2545 {
2546 if(husb->devresumecallback != NULL)
2547 husb->devresumecallback(husb);
2548 }
2549 husb->lx_state = DWC2_L0;
2550 clear_dev_int(base, USB_OTG_GINTSTS_WKUINT);
2551 }
2552 /*
2553 * SUSPEND割込み
2554 */
2555 if((get_int_status(base, msk) & USB_OTG_GINTSTS_USBSUSP) != 0){
2556 if((sil_rew_mem((uint32_t *)(USBD_BASE(base)+TOFF_USBD_DSTS)) & USB_OTG_DSTS_SUSPSTS) != 0){
2557 usbo_enter_hibernation(husb); /* 省エネ移行 */
2558 if(husb->devsuspendcallback != NULL && husb->connected)
2559 husb->devsuspendcallback(husb);
2560 if(husb->Init.usb_otg_mode == USB_OTG_MODE_DRD && husb->hostdisconnectcallback != NULL && husb->connected){
2561 syslog_1(LOG_NOTICE, "usbo_pcd_irqhandler drd mode disconnect lx_state(%d) !", husb->lx_state);
2562 husb->connected = 0;
2563 husb->hostdisconnectcallback(husb);
2564 }
2565 husb->lx_state = DWC2_L2;
2566 }
2567 clear_dev_int(base, USB_OTG_GINTSTS_USBSUSP);
2568 }
2569#ifdef USB_OTG_GLPMCFG_LPMEN
2570 /*
2571 * LPM割込み
2572 */
2573 if((get_int_status(base, msk) & USB_OTG_GINTSTS_LPMINT) != 0){
2574 clear_dev_int(base, USB_OTG_GINTSTS_LPMINT);
2575 if(husb->lpm_state == PCD_LPM_L0_ACTIVE){
2576 husb->lpm_state = PCD_LPM_L1_ACTIVE;
2577 husb->BESL = (sil_rew_mem((uint32_t *)(USBOTG_BASE(base)+TOFF_USBO_GLPMCFG)) & USB_OTG_GLPMCFG_BESL) >>2 ;
2578 if(husb->devlpmcallback != NULL)
2579 husb->devlpmcallback(husb, PCD_LPM_L1_ACTIVE);
2580 husb->lx_state = DWC2_L1;
2581 }
2582 else{
2583 if(husb->devsuspendcallback != NULL)
2584 husb->devsuspendcallback(husb);
2585 husb->lx_state = DWC2_L2;
2586 }
2587 }
2588#endif /* USB_OTG_GLPMCFG_LPMEN */
2589 /*
2590 * USB-RESET割込み
2591 */
2592 if((get_int_status(base, msk) & USB_OTG_GINTSTS_USBRST) != 0){
2593 sil_andw_mem((uint32_t *)(USBD_BASE(base)+TOFF_USBD_DCTL), USB_OTG_DCTL_RWUSIG);
2594 usbo_flushTxFifo(husb, 0U);
2595 for(i = 0; i < husb->Init.dev_endpoints ; i++){
2596 sil_wrw_mem((uint32_t *)(USBIEP_BASE(base, i)+TOFF_USBEI_DIEPINT), 0xFF);
2597 sil_wrw_mem((uint32_t *)(USBOEP_BASE(base, 0)+TOFF_USBEO_DOEPINT), 0xFF);
2598 }
2599 sil_wrw_mem((uint32_t *)(USBD_BASE(base)+TOFF_USBD_DAINT), 0xFFFFFFFF);
2600 sil_orw_mem((uint32_t *)(USBD_BASE(base)+TOFF_USBD_DAINTMSK), 0x10001);
2601 if(husb->Init.use_dedicated_ep1){
2602 sil_orw_mem((uint32_t *)(USBD_BASE(base)+TOFF_USBD_DOUTEP1MSK), (USB_OTG_DOEPMSK_STUPM | USB_OTG_DOEPMSK_XFRCM | USB_OTG_DOEPMSK_EPDM));
2603 sil_orw_mem((uint32_t *)(USBD_BASE(base)+TOFF_USBD_DINEP1MSK), (USB_OTG_DIEPMSK_TOM | USB_OTG_DIEPMSK_XFRCM | USB_OTG_DIEPMSK_EPDM));
2604 }
2605 else{
2606#ifdef USB_OTG_DOEPINT_OTEPSPR
2607 sil_orw_mem((uint32_t *)(USBD_BASE(base)+TOFF_USBD_DOEPMSK), (USB_OTG_DOEPMSK_STUPM | USB_OTG_DOEPMSK_XFRCM | USB_OTG_DOEPMSK_EPDM | USB_OTG_DOEPMSK_OTEPSPRM));
2608#else
2609 sil_orw_mem((uint32_t *)(USBD_BASE(base)+TOFF_USBD_DOEPMSK), (USB_OTG_DOEPMSK_STUPM | USB_OTG_DOEPMSK_XFRCM | USB_OTG_DOEPMSK_EPDM));
2610#endif /* USB_OTG_DOEPINT_OTEPSPR */
2611 sil_orw_mem((uint32_t *)(USBD_BASE(base)+TOFF_USBD_DIEPMSK), (USB_OTG_DIEPMSK_TOM | USB_OTG_DIEPMSK_XFRCM | USB_OTG_DIEPMSK_EPDM));
2612 }
2613 /*
2614 * デフォルトアドレスをゼロに設定
2615 */
2616 sil_andw_mem((uint32_t *)(USBD_BASE(base)+TOFF_USBD_DCFG), USB_OTG_DCFG_DAD);
2617 /*
2618 * SETUPパケット受信設定
2619 */
2620 usbo_ep0_outstart(husb, (uint8_t *)husb->Setup);
2621 clear_dev_int(base, USB_OTG_GINTSTS_USBRST);
2622 }
2623 /*
2624 * ENUMERATIONハンドル終了割込み
2625 */
2626 if((get_int_status(base, msk) & USB_OTG_GINTSTS_ENUMDNE) != 0){
2627 /*
2628 * USBアクティベートセットアップ
2629 */
2630 sil_andw_mem((uint32_t *)(USBIEP_BASE(base, 0)+TOFF_USBEI_DIEPCTL), USB_OTG_DIEPCTL_MPSIZ);
2631 if((sil_rew_mem((uint32_t *)(USBD_BASE(base)+TOFF_USBD_DSTS)) & USB_OTG_DSTS_ENUMSPD) == DSTS_ENUMSPD_LS_PHY_6MHZ){
2632 sil_orw_mem((uint32_t *)(USBIEP_BASE(base, 0)+TOFF_USBEI_DIEPCTL), 3);
2633 }
2634 sil_orw_mem((uint32_t *)(USBD_BASE(base)+TOFF_USBD_DCTL), USB_OTG_DCTL_CGINAK);
2635
2636 sil_andw_mem((uint32_t *)(USBOTG_BASE(base)+TOFF_USBO_GUSBCFG), USB_OTG_GUSBCFG_TRDT);
2637 if(usbo_getDevSpeed(husb) == USB_SPEED_HIGH){
2638 husb->Init.speed = USB_SPEED_HIGH;
2639 sil_orw_mem((uint32_t *)(USBOTG_BASE(base)+TOFF_USBO_GUSBCFG), ((USBD_HS_TRDT_VALUE << 10) & USB_OTG_GUSBCFG_TRDT));
2640 }
2641 else{
2642 husb->Init.speed = USB_SPEED_FULL;
2643
2644 /*
2645 * USBTRDTの設定は、AHB周期設定(SysFreHCLK)に従う
2646 */
2647#if (SysFreHCLK < 15000000) /* under 15MHz */
2648 temp = 0x0F;
2649#elif (SysFreHCLK >= 15000000) && (SysFreHCLK < 16000000) /* 15Mhz-16MHz */
2650 temp = 0x0E;
2651#elif (SysFreHCLK >= 16000000) && (SysFreHCLK < 17200000) /* 16MHz-17.2MHz */
2652 temp = 0x0D;
2653#elif (SysFreHCLK >= 17200000) && (SysFreHCLK < 18500000) /* 17.2MHz-18.5MHz */
2654 temp = 0x0C;
2655#elif (SysFreHCLK >= 18500000) && (SysFreHCLK < 20000000) /* 18.5MHz-20MHz */
2656 temp = 0x0B;
2657#elif (SysFreHCLK >= 20000000) && (SysFreHCLK < 21800000) /* 20MHz-21.8MHz */
2658 temp = 0x0A;
2659#elif (SysFreHCLK >= 21800000) && (SysFreHCLK < 24000000) /* 21.8MHz-24MHz */
2660 temp = 0x09;
2661#elif (SysFreHCLK >= 24000000) && (SysFreHCLK < 27700000) /* 24MHz-27.7MHz */
2662 temp = 0x08;
2663#elif (SysFreHCLK >= 27700000) && (SysFreHCLK < 32000000) /* 27.7MHz-32MHz */
2664 temp = 0x07;
2665#else /* over 32MHz */
2666 temp = 0x06;
2667#endif
2668 sil_orw_mem((uint32_t *)(USBOTG_BASE(base)+TOFF_USBO_GUSBCFG), ((temp << 10) & USB_OTG_GUSBCFG_TRDT));
2669 }
2670 if(husb->devresetcallback != NULL)
2671 husb->devresetcallback(husb);
2672 clear_dev_int(base, USB_OTG_GINTSTS_ENUMDNE);
2673 }
2674 /*
2675 * RXQLEVEL割込み
2676 */
2677 if((get_int_status(base, msk) & USB_OTG_GINTSTS_RXFLVL) != 0){
2678 sil_andw_mem((uint32_t *)(USBOTG_BASE(base)+TOFF_USBO_GINTMSK), USB_OTG_GINTSTS_RXFLVL);
2679 temp = sil_rew_mem((uint32_t *)(USBOTG_BASE(base)+TOFF_USBO_GRXSTSP));
2680 ep = &husb->OUT_ep[temp & USB_OTG_GRXSTSP_EPNUM];
2681 if(((temp & USB_OTG_GRXSTSP_PKTSTS) >> 17U) == STS_DATA_UPDT){
2682 if((temp & USB_OTG_GRXSTSP_BCNT) != 0){
2683 usbo_readPacket(base, ep->xfer_buff, (temp & USB_OTG_GRXSTSP_BCNT) >> 4U);
2684 ep->xfer_buff += (temp & USB_OTG_GRXSTSP_BCNT) >> 4U;
2685 ep->xfer_count += (temp & USB_OTG_GRXSTSP_BCNT) >> 4U;
2686 }
2687 }
2688 else if(((temp & USB_OTG_GRXSTSP_PKTSTS) >> 17U) == STS_SETUP_UPDT){
2689 usbo_readPacket(base, (uint8_t *)husb->Setup, 8U);
2690 ep->xfer_count += (temp & USB_OTG_GRXSTSP_BCNT) >> 4U;
2691 }
2692 sil_orw_mem((uint32_t *)(USBOTG_BASE(base)+TOFF_USBO_GINTMSK), USB_OTG_GINTSTS_RXFLVL);
2693 }
2694 /*
2695 * DEVICE-SOF割込み
2696 */
2697 if((get_int_status(base, msk) & USB_OTG_GINTSTS_SOF) != 0){
2698 if(husb->devsofcallback != NULL)
2699 husb->devsofcallback(husb);
2700 clear_dev_int(base, USB_OTG_GINTSTS_SOF);
2701 }
2702 /*
2703 * ISO IN未完結割込み
2704 */
2705 if((get_int_status(base, msk) & USB_OTG_GINTSTS_IISOIXFR) != 0){
2706 if(husb->devisoincallback != NULL)
2707 husb->devisoincallback(husb, epnum);
2708 clear_dev_int(base, USB_OTG_GINTSTS_IISOIXFR);
2709 }
2710 /*
2711 * ISO OUT未完結割込み
2712 */
2713 if((get_int_status(base, msk) & USB_OTG_GINTSTS_PXFR_INCOMPISOOUT) != 0){
2714 if(husb->devisooutcallback != NULL)
2715 husb->devisooutcallback(husb, epnum);
2716 clear_dev_int(base, USB_OTG_GINTSTS_PXFR_INCOMPISOOUT);
2717 }
2718 /*
2719 * コネクションイベント割込み
2720 */
2721 if((get_int_status(base, msk) & USB_OTG_GINTSTS_SRQINT) != 0){
2722 if(husb->devconnectcallback != NULL)
2723 husb->devconnectcallback(husb);
2724 clear_dev_int(base, USB_OTG_GINTSTS_SRQINT);
2725 }
2726 /*
2727 * ディスコネクションイベント割込み
2728 */
2729 if((get_int_status(base, msk) & USB_OTG_GINTSTS_OTGINT) != 0){
2730 temp = sil_rew_mem((uint32_t *)(USBOTG_BASE(base)+TOFF_USBO_GOTGINT));
2731 if((temp & USB_OTG_GOTGINT_SEDET) == USB_OTG_GOTGINT_SEDET){
2732 husb->connected = 0;
2733 if(husb->devdisconnectcallback != NULL)
2734 husb->devdisconnectcallback(husb);
2735 }
2736 sil_orw_mem((uint32_t *)(USBOTG_BASE(base)+TOFF_USBO_GOTGINT), temp);
2737 }
2738}
2739
2740/*
2741 * USB-OTG割込みサービスルーチン
2742 */
2743void
2744usb_otg_isr(intptr_t exinf)
2745{
2746 USB_OTG_Handle_t *husb = &Husb[INDEX_USB((uint32_t)exinf)];
2747 if(get_usbmode(husb->base) == USB_OTG_MODE_DEVICE){
2748 usbo_pcd_irqhandler(husb);
2749 }
2750 else{
2751 usbo_hcd_irqhandler(husb);
2752 }
2753}
2754
2755/*
2756 * USB-OTG WAKEUP割込みサービスルーチン
2757 */
2758void usb_otg_wkup_isr(intptr_t exinf)
2759{
2760 USB_OTG_Handle_t *husb = &Husb[INDEX_USB((uint32_t)exinf)];
2761
2762 if(husb->Init.low_power_enable){
2763 /*
2764 * Cortex SLEEPDEEPビットリセット
2765 */
2766 sil_andw_mem((uint32_t *)(TADR_SCB_BASE+TOFF_SCB_SCR), (SCB_SCR_SLEEPDEEP_Msk | SCB_SCR_SLEEPONEXIT_Msk));
2767#if !defined(TOPPERS_STM32F4_DISCOVERY)
2768 /*
2769 * 起動クロック再設定
2770 */
2771 sysclock_config(0);
2772#endif
2773 }
2774
2775 /* ungate PHY clock */
2776 sil_andw_mem((uint32_t *)(USBPGC_BASE(husb->base)), USB_OTG_PCGCCTL_STOPCLK);
2777
2778#ifdef EXTI_PR_BASE
2779 /*
2780 * EXTI WAKEUPペンディングビットクリア
2781 */
2782 sil_wrw_mem((uint32_t *)EXTI_PR_BASE, USB_OTG_FS_WAKEUP_EXTI_LINE);
2783#endif
2784}
2785
Note: See TracBrowser for help on using the repository browser.