28
28
29
29
#define STLINK_VID 0x0483
30
30
#define STLINK_PID 0x3748
31
+ #define STLINK_PIDV21 0x374b
32
+ #define STLINK_PIDV21_MSD 0x3752
33
+ #define STLINK_PIDV3 0x374f
34
+ #define STLINK_PIDV3_BL 0x374d
35
+
36
+ #define OPENMOKO_VID 0x1d50
37
+ #define BMP_APPL_PID 0x6018
38
+ #define BMP_DFU_IF 4
31
39
32
40
void print_help (char * argv []) {
33
41
printf ("Usage: %s [options] [firmware.bin]\n" , argv [0 ]);
@@ -37,11 +45,10 @@ void print_help(char *argv[]) {
37
45
printf ("\tApplication is started when called without argument or after firmware load\n\n" );
38
46
}
39
47
48
+ #include <string.h>
40
49
int main (int argc , char * argv []) {
41
- libusb_context * usb_ctx ;
42
- libusb_device_handle * dev_handle ;
43
- struct STLinkInfos infos ;
44
- int res , i , opt , probe = 0 ;
50
+ struct STLinkInfo info ;
51
+ int res = EXIT_FAILURE , i , opt , probe = 0 ;
45
52
46
53
while ((opt = getopt (argc , argv , "hp" )) != -1 ) {
47
54
switch (opt ) {
@@ -61,63 +68,147 @@ int main(int argc, char *argv[]) {
61
68
62
69
int do_load = (optind < argc );
63
70
64
- res = libusb_init (& usb_ctx );
65
- (void )res ;
66
-
67
- dev_handle = libusb_open_device_with_vid_pid (usb_ctx ,
68
- STLINK_VID ,
69
- STLINK_PID );
70
- if (!dev_handle ) {
71
- fprintf (stderr , "No ST-Link in DFU mode found. Replug ST-Link to flash!\n" );
72
- return EXIT_FAILURE ;
73
- }
71
+ res = libusb_init (& info .stinfo_usb_ctx );
72
+ rescan :
73
+ info .stinfo_dev_handle = NULL ;
74
+ libusb_device * * devs ;
75
+ int n_devs = libusb_get_device_list (info .stinfo_usb_ctx , & devs );
76
+ if (n_devs < 0 )
77
+ goto exit_libusb ;
78
+ for (int i = 0 ; devs [i ]; i ++ ) {
79
+ libusb_device * dev = devs [i ];
80
+ struct libusb_device_descriptor desc ;
81
+ int res = libusb_get_device_descriptor (dev , & desc );
82
+ if (res < 0 )
83
+ continue ;
84
+ if ((desc .idVendor == OPENMOKO_VID ) && (desc .idProduct == BMP_APPL_PID )) {
85
+ res = libusb_open (dev , & info .stinfo_dev_handle );
86
+ if (res < 0 ) {
87
+ fprintf (stderr , "Can not open BMP/Application!\n" );
88
+ continue ;
89
+ }
90
+ libusb_claim_interface (info .stinfo_dev_handle , BMP_DFU_IF );
91
+ res = libusb_control_transfer (
92
+ info .stinfo_dev_handle ,
93
+ /* bmRequestType */ LIBUSB_ENDPOINT_OUT | LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_RECIPIENT_INTERFACE ,
94
+ /* bRequest */ 0 , /*DFU_DETACH,*/
95
+ /* wValue */ 1000 ,
96
+ /* wIndex */ BMP_DFU_IF ,
97
+ /* Data */ NULL ,
98
+ /* wLength */ 0 ,
99
+ 5000 );
100
+ libusb_release_interface (info .stinfo_dev_handle , 0 );
101
+ if (res < 0 ) {
102
+ fprintf (stderr , "BMP Switch failed\n" );
103
+ continue ;
104
+ }
105
+ libusb_free_device_list (devs , 1 );
106
+ usleep (2000000 );
107
+ goto rescan ;
108
+ break ;
109
+ }
110
+ if (desc .idVendor != STLINK_VID )
111
+ continue ;
112
+ switch (desc .idProduct ) {
113
+ case STLINK_PID :
114
+ res = libusb_open (dev , & info .stinfo_dev_handle );
115
+ if (res < 0 ) {
116
+ fprintf (stderr , "Can not open STLINK/Bootloader!\n" );
117
+ continue ;
118
+ }
119
+ info .stinfo_ep_in = 1 | LIBUSB_ENDPOINT_IN ;
120
+ info .stinfo_ep_out = 2 | LIBUSB_ENDPOINT_OUT ;
121
+ info .stinfo_bl_type = STLINK_BL_V2 ;
122
+ fprintf (stderr , "StlinkV21 Bootloader found\n" );
123
+ break ;
124
+ case STLINK_PIDV3_BL :
125
+ res = libusb_open (dev , & info .stinfo_dev_handle );
126
+ if (res < 0 ) {
127
+ fprintf (stderr , "Can not open STLINK-V3/Bootloader!\n" );
128
+ continue ;
129
+ }
130
+ info .stinfo_ep_in = 1 | LIBUSB_ENDPOINT_IN ;
131
+ info .stinfo_ep_out = 1 | LIBUSB_ENDPOINT_OUT ;
132
+ info .stinfo_bl_type = STLINK_BL_V3 ;
133
+ fprintf (stderr , "StlinkV3 Bootloader found\n" );
134
+ break ;
135
+ case STLINK_PIDV21 :
136
+ case STLINK_PIDV21_MSD :
137
+ case STLINK_PIDV3 :
138
+ res = libusb_open (dev , & info .stinfo_dev_handle );
139
+ if (res < 0 ) {
140
+ fprintf (stderr , "Can not open STLINK/Application!\n" );
141
+ continue ;
142
+ }
143
+ res = stlink_dfu_mode (info .stinfo_dev_handle , 0 );
144
+ if (res != 0x8000 ) {
145
+ libusb_release_interface (info .stinfo_dev_handle , 0 );
146
+ return 0 ;
147
+ }
148
+ stlink_dfu_mode (info .stinfo_dev_handle , 1 );
149
+ libusb_release_interface (info .stinfo_dev_handle , 0 );
150
+ libusb_free_device_list (devs , 1 );
151
+ fprintf (stderr , "Trying to switch STLINK/Application to bootloader\n" );
152
+ usleep (2000000 );
153
+ goto rescan ;
154
+ break ;
155
+ }
156
+ if (info .stinfo_dev_handle )
157
+ break ;}
158
+ libusb_free_device_list (devs , 1 );
159
+ if (!info .stinfo_dev_handle ) {
160
+ fprintf (stderr , "No ST-Link in DFU mode found. Replug ST-Link to flash!\n" );
161
+ return EXIT_FAILURE ;
162
+ }
74
163
75
- if (libusb_claim_interface (dev_handle , 0 )) {
76
- fprintf (stderr , "Unable to claim USB interface ! Please close all programs that may communicate with an ST-Link dongle.\n" );
164
+ if (libusb_claim_interface (info .stinfo_dev_handle , 0 )) {
165
+ fprintf (stderr , "Unable to claim USB interface ! Please close all programs that "
166
+ "may communicate with an ST-Link dongle.\n" );
77
167
return EXIT_FAILURE ;
78
168
}
79
169
80
- if (stlink_read_infos ( dev_handle , & infos )) {
81
- libusb_release_interface (dev_handle , 0 );
170
+ if (stlink_read_info ( & info )) {
171
+ libusb_release_interface (info . stinfo_dev_handle , 0 );
82
172
return EXIT_FAILURE ;
83
173
}
84
-
85
- printf ("Firmware version : V%dJ%dS%d\n" , infos .stlink_version ,
86
- infos .jtag_version , infos .swim_version );
87
- printf ("Loader version : %d\n" , infos .loader_version );
174
+ printf ("Firmware version : V%dJ%dS%d\n" , info .stlink_version ,
175
+ info .jtag_version , info .swim_version );
176
+ printf ("Loader version : %d\n" , info .loader_version );
88
177
printf ("ST-Link ID : " );
89
- for (i = 0 ; i < 12 ; i ++ ) {
90
- printf ("%02X" , infos .id [i ]);
178
+ for (i = 0 ; i < 12 ; i += 4 ) {
179
+ printf ("%02X" , info .id [i + 3 ]);
180
+ printf ("%02X" , info .id [i + 2 ]);
181
+ printf ("%02X" , info .id [i + 1 ]);
182
+ printf ("%02X" , info .id [i + 0 ]);
91
183
}
92
184
printf ("\n" );
93
185
printf ("Firmware encryption key : " );
94
186
for (i = 0 ; i < 16 ; i ++ ) {
95
- printf ("%02X" , infos .firmware_key [i ]);
187
+ printf ("%02X" , info .firmware_key [i ]);
96
188
}
97
189
printf ("\n" );
98
190
99
- res = stlink_current_mode (dev_handle );
191
+ res = stlink_current_mode (& info );
100
192
if (res < 0 ) {
101
- libusb_release_interface (dev_handle , 0 );
193
+ libusb_release_interface (info . stinfo_dev_handle , 0 );
102
194
return EXIT_FAILURE ;
103
195
}
104
196
printf ("Current mode : %d\n" , res );
105
197
106
- if (res != 1 ) {
198
+ if (res & 0xfffc ) {
107
199
printf ("ST-Link dongle is not in the correct mode. Please unplug and plug the dongle again.\n" );
108
- libusb_release_interface (dev_handle , 0 );
200
+ libusb_release_interface (info . stinfo_dev_handle , 0 );
109
201
return EXIT_SUCCESS ;
110
202
}
111
203
112
204
if (!probe ) {
113
- if (do_load ) {
114
- stlink_flash (dev_handle , argv [optind ], 0x8004000 , 1024 , & infos );
205
+ if (do_load )
206
+ stlink_flash (& info , argv [optind ]);
207
+ stlink_exit_dfu (& info );
115
208
}
116
- stlink_exit_dfu (dev_handle );
117
- }
118
-
119
- libusb_release_interface (dev_handle , 0 );
120
- libusb_exit (usb_ctx );
209
+ libusb_release_interface (info .stinfo_dev_handle , 0 );
210
+ exit_libusb :
211
+ libusb_exit (info .stinfo_usb_ctx );
121
212
122
213
return EXIT_SUCCESS ;
123
214
}
0 commit comments