学习了f767的USB相关例程,本想直接移植到f769,但是f767的例程里面没有USB的PHY,不能实现高速,而f769的板载有PHY可以实现高速功能, L0 N0 y: H; v( J
3 ?& R _ ?# U+ c2 B
见上图,是板载的PHY芯片,可以实现USB是高速传输,. d7 g! J5 n, i3 L
既然不能直接移植,就只能通过官方的例程移植了,于是在之前实现的SD卡移植fatfs的例程的基础上继续移植实现USB-slave读卡器的功能。参考官方的相关例程,准备好了目录及相关源文件,见下图
. O% c" D% p4 W, r - k1 y9 n0 T$ D6 t7 T
其中pcd_usb.c文件是转化的官方例程的stm32f7xx_hal_pcd.c和stm32f7xx_ll_usb.c及相关的头文件而来的usb相关配置及操作的函数,就不一一介绍了。5 \! I* L/ X& u5 v% v8 B: y
下面主要讲解一下usbd_conf.c和usbd_storage.c。而usbd_desc.c这个文件本就是官方为配置板卡的,所以不用任何改动即可。
8 R0 J# Q2 H% h, E在usbd_conf.c里面需要改动的有HAL_PCD_MspInit()函数,里面是USB相关的IO口配置及初始化。
. M3 b" m; W' A+ `3 V) M% \$ @2 [+ w; P2 S1 ~
- A) T! e& [; } /* Configure USB FS GPIOs */- z# `7 J8 H1 w- }/ c
3 L7 }9 r. d( d2 t' w- k
*(uint32_t *)0x40023830 |= 7<<0 | 3<< 7;8 h+ \* w3 `6 r+ {: p" W
/* CLK */
& O c) m( b" E3 I GPIO_Set(GPIOA,PIN3|PIN5,GPIO_MODE_AF,GPIO_OTYPE_PP,GPIO_SPEED_100M,GPIO_PUPD_NONE);//PA9,PA10,复用功能,上拉输出
3 u6 V4 a: w) D, X; H B3 y GPIO_AF_Set(GPIOA,3,10); //PA38 z8 n! _7 ~9 g# c$ y' l
GPIO_AF_Set(GPIOA,5,10); //PA5
) f/ K0 J4 Y8 b% P/* D1 D2 D3 D4 D5 D6 D7 */
% i5 @2 |4 M9 A: [& W GPIO_Set(GPIOB,PIN0|PIN1|PIN5|PIN10|PIN11|PIN12|PIN13,GPIO_MODE_AF,GPIO_OTYPE_PP,GPIO_SPEED_100M,GPIO_PUPD_NONE);//PA9,PA10,复用功能,上拉输出1 P+ g% _$ K7 M1 o: @
GPIO_AF_Set(GPIOB,0,10); //PA3" F) [) R3 ^) Q+ J) h) p
GPIO_AF_Set(GPIOB,1,10); //PA50 @, \ F+ Z5 _2 W
GPIO_AF_Set(GPIOB,5,10); //PA5
8 a0 X \ R, H0 J GPIO_AF_Set(GPIOB,10,10); //PA5
4 M: R% R8 u+ ~, @! ~' r GPIO_AF_Set(GPIOB,11,10); //PA5
- Q6 J, Z5 B6 m GPIO_AF_Set(GPIOB,12,10); //PA5$ g* h' i, ?5 j4 O
GPIO_AF_Set(GPIOB,13,10); //PA5
: ^/ Q9 d: |/ [9 b8 X3 n% U/* STP */
" V2 k( e. b* j3 M* v. x! T" y GPIO_Set(GPIOC,PIN0,GPIO_MODE_AF,GPIO_OTYPE_PP,GPIO_SPEED_100M,GPIO_PUPD_NONE);//PA9,PA10,复用功能,上拉输出
. @2 U6 F$ t% t' a4 T GPIO_AF_Set(GPIOC,0,10); //PA3
0 i7 Q$ X5 P) k% v/ V0 P/ M$ y. K/* NXT */
% X' ]; O3 B2 [5 v( Q7 @& W8 ~1 V GPIO_Set(GPIOH,PIN4,GPIO_MODE_AF,GPIO_OTYPE_PP,GPIO_SPEED_100M,GPIO_PUPD_NONE);//PA9,PA10,复用功能,上拉输出
4 ^0 d8 c& H; W7 C N9 B6 c$ _; I& q GPIO_AF_Set(GPIOH,4,10); //PA3
, z6 l# o F% D1 q& X. W5 V/* DIR *// v) h* y/ Y) t8 G) o
GPIO_Set(GPIOI,PIN11,GPIO_MODE_AF,GPIO_OTYPE_PP,GPIO_SPEED_100M,GPIO_PUPD_NONE);//PA9,PA10,复用功能,上拉输出
, s7 |) `+ G+ R" G0 q; O GPIO_AF_Set(GPIOI,11,10); //PA36 g* L( R; g7 k# m
" O( u' }8 ^3 S
/* Enable USB HS Clocks */' ?' O7 P/ K2 L1 w7 a
*(uint32_t *)0x40023830 |= 3<< 29;- t1 ^. x0 M5 o- V
prioritygroup = NVIC_GetPriorityGrouping();
, x$ k' ?# I$ E* ?& M6 k
3 ]- F0 d4 z }- O& N /* Set USBHS Interrupt to the lowest priority */( ^/ H1 P& y: E; [
NVIC_SetPriority(OTG_HS_IRQn, NVIC_EncodePriority(prioritygroup, 0x0F, 0));6 P% |6 I0 _8 D$ j+ E
* T, O* G! a" t% Q, [
/* Enable USBHS Interrupt */" Q& E7 v& z. j3 J: P
NVIC_EnableIRQ(OTG_HS_IRQn);
! W& U* C0 {: v0 s# [里面有相关的注释,不用过多讲解,其他的函数不需要改动,% j/ Q7 J' {6 H E' R
在usbd_storage.c里面需要改动的有
* t4 l; j! ^) a) _7 ^* X# CSTORAGE_GetCapacity()函数按下面更改
) g, \: h7 V3 G- U# O, E- dint8_t STORAGE_GetCapacity(uint8_t lun, uint32_t *block_num, uint16_t *block_size)" U4 x6 e$ d- B0 ]! g
{4 g" j3 j% i! Y {% ~0 w
SD_CardInfo info;6 G2 z& w& b# O2 o5 N
int8_t ret = -1; 9 b' j/ g* u9 z4 l6 H2 |" L$ Z
, G; n- T' U6 {* o' T$ ? % T5 I/ y! v" r- z* K
SD_GetCardInfo(&info);
6 b9 v5 v7 Y# k0 m# m
`8 k) [6 f2 m! `$ N8 i8 L0 k % P1 ~5 R0 G) }$ V" O
ret = 0;
% {$ n* Q- C7 m: ?8 B6 e3 @2 F: O0 v" f4 e5 l
return ret;) k3 `4 G' v9 s1 D6 D4 }* N. }
}
$ ^ I9 C' h. @7 X" y2 i* `STORAGE_IsReady()函数按下面更改, ^5 c4 Z6 a5 z8 o& ?
int8_t STORAGE_IsReady(uint8_t lun)$ `. l5 }0 j& U) b7 f
{' e6 _, o$ Z; [2 |( w( V
static int8_t prev_status = 0;
$ ]) m2 C/ D: T7 m) E8 I int8_t ret = -1;
1 q! W* V7 i4 R/ Q% P! f
# Q' Y$ e4 U2 W3 ~& e& w6 f0 c( E3 A1 I0 h! ]* v" o% ^
if(prev_status < 0)
3 g3 e0 t+ B/ N2 {# f" O {
: y: B: R! X6 M. i- s' W sdcard_init();
% c _2 E$ T. N( m# K" v0 w prev_status = 0;
' U# w" q8 x* C7 V/ J
! M& N! x; ]) N% z7 z; q3 w }6 E8 t- ]$ P8 q. r% C2 k
- m) h' I: ^9 Y9 v" H7 p" a5 [9 g$ L" P, H% T! K H
else if(prev_status == 0)
8 ?' D: d1 {: y4 ? {1 `, H" t4 M! ~; @! ?- j u
prev_status = -1;- S" A. A& s6 d$ C |6 N( w
}" v6 ~& t8 u0 q! d
return ret;; a0 \% C* n" y5 i7 l- x) g
}
! w, ?5 [: @9 f9 o9 K5 HSTORAGE_Read()函数按下面更改
) y! l! H( o1 \ {0 Nint8_t STORAGE_Read(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len) m: Q+ h6 t, x* g1 O# l" q
{
) [/ R7 N- B( |! b# |) b int8_t ret = -1;
4 Q6 ~( n @2 G/ D0 h3 D
4 H. _& y# i' A" B
0 x3 c1 K. S' [ SD_ReadBlocks((uint8_t *)buf, blk_addr, blk_len, 1000);
" g8 N1 ~9 z4 R! A5 F( ?/ a ret = 0;
6 a5 w% @/ ~6 R5 G4 L- S7 X# S* s9 Y2 {1 Q) D9 z- D2 e" `
return ret;
6 x1 k: t$ ]: O- U: \1 S! F}
9 Q- g# J4 r9 JSTORAGE_Write()函数按下面更改
5 k# B8 P- B h% y- int8_t STORAGE_Write(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len)
- {
- int8_t ret = -1;
- SD_WriteBlocks((uint8_t *)buf, blk_addr, blk_len, 1000);
- ret = 0;
- return ret;
- }
0 X& f! h. L7 \! E1 @& o* L, a$ | . \! G8 k1 g% a H4 l
[color=rgb(51, 102, 153) !important]复制代码+ C5 S' M% q) ^, @; ^: ^3 W
好了,全部更改完成,编译通过,可以增加在main函数里面的初始化了9 ^" `9 K& o+ g, k7 W# ?
直接把官方例程中的代码拷贝过来即可6 F; z1 J/ \$ ]( x6 p
- /* Init Device Library */
- USBD_Init(&USBD_Device, &MSC_Desc, 0);
- /* Add Supported Class */
- USBD_RegisterClass(&USBD_Device, USBD_MSC_CLASS);
- /* Add Storage callbacks for MSC Class */
- USBD_MSC_RegisterStorage(&USBD_Device, &USBD_DISK_fops);
- /* Start Device Process */
- USBD_Start(&USBD_Device); o3 D1 w6 T1 X4 ?
, F" L+ A* \, ]9 S0 F4 G" i/ K0 u1 }[color=rgb(51, 102, 153) !important]复制代码/ m& m, |; }2 n" M6 J r
编译完成,下载,在设备管理器会出现如下
+ Z2 \7 o7 O5 ^# ]" X# j I% H 5 Z p0 G, G7 Q+ H) n
其中便携设备的H盘,磁盘驱动器的STM Product USB Device还有通用串行总线控制器的USB大容量存储设备,说明移植成功,和直接下载官方例程是一样的效果。
/ E+ y% ^0 g5 {, i6 K/ o6 L" W3 O0 V8 Q% n9 E7 |) o$ ]! ~ Q
! B7 z" l: t1 G$ v3 M
发贴于2018年4月4日
* p8 p' A% i3 H3 m, N |
https://www.stmcu.org.cn/module/forum/thread-615497-1-1.html