@@ -38,14 +38,16 @@ int echo_buffer_len;
3838int num_echos ;
3939
4040
41- // Blink durations
42- enum {
43- BLINK_NOT_MOUNTED = 250 ,
44- BLINK_MOUNTED = 1000 ,
45- };
41+ static bool is_blinking = true;
42+ static uint32_t led_on_until = 0 ;
43+ static uint32_t blink_toogle_at = 0 ;
44+ static bool is_blink_on = true;
4645
47- static uint32_t blink_interval_ms = BLINK_NOT_MOUNTED ;
46+ static inline bool has_expired (uint32_t deadline , uint32_t now ) {
47+ return (int32_t )(now - deadline ) >= 0 ;
48+ }
4849
50+ static void led_busy (void );
4951static void led_blinking_task (void );
5052static void loopback_init (void );
5153static void loopback_check_rx (void );
@@ -93,6 +95,7 @@ void loopback_check_tx(void) {
9395 n = max_size ;
9496
9597 cust_vendor_start_transmit_fifo (EP_LOOPBACK_TX , & loopback_fifo , n );
98+ led_busy ();
9699 }
97100}
98101
@@ -110,6 +113,7 @@ void loopback_check_rx(void) {
110113void echo_update_state (void ) {
111114 if (num_echos > 0 ) {
112115 cust_vendor_start_transmit (EP_ECHO_TX , echo_buffer , echo_buffer_len );
116+ led_busy ();
113117 } else {
114118 cust_vendor_prepare_recv (EP_ECHO_RX , echo_buffer , sizeof (echo_buffer ));
115119 }
@@ -129,6 +133,7 @@ void cust_vendor_rx_cb(uint8_t ep_addr, uint32_t recv_bytes) {
129133 echo_buffer_len = recv_bytes ;
130134 echo_update_state ();
131135 }
136+ led_busy ();
132137}
133138
134139// Invoked when last tx transfer finished
@@ -139,8 +144,10 @@ void cust_vendor_tx_cb(uint8_t ep_addr, uint32_t sent_bytes) {
139144
140145 // check ZLP
141146 if ((sent_bytes & (bulk_packet_size - 1 )) == 0
142- && !cust_vendor_is_transmitting (ep_addr ))
147+ && !cust_vendor_is_transmitting (ep_addr )) {
143148 cust_vendor_start_transmit (EP_LOOPBACK_TX , NULL , 0 );
149+ led_busy ();
150+ }
144151
145152 } else if (ep_addr == EP_ECHO_TX ) {
146153 num_echos -- ;
@@ -153,6 +160,7 @@ void cust_vendor_intf_open_cb(uint8_t intf) {
153160 bulk_packet_size = cust_vendor_packet_size (EP_LOOPBACK_RX );
154161 loopback_check_rx ();
155162 echo_update_state ();
163+ led_busy ();
156164}
157165
158166// Invoked when an alternate interface has been selected
@@ -162,6 +170,7 @@ void cust_vendor_alt_intf_selected_cb(uint8_t intf, uint8_t alt) {
162170 loopback_check_rx ();
163171 if (alt == 0 )
164172 echo_update_state ();
173+ led_busy ();
165174}
166175
167176void cust_vendor_halt_cleared_cb (uint8_t ep_addr ) {
@@ -183,6 +192,7 @@ void cust_vendor_halt_cleared_cb(uint8_t ep_addr) {
183192 default :
184193 break ;
185194 }
195+ led_busy ();
186196}
187197
188198
@@ -209,27 +219,31 @@ bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_requ
209219 if (request -> bmRequestType_bit .direction == TUSB_DIR_OUT && request -> wLength == 0 ) {
210220 // save value from wValue
211221 saved_value = request -> wValue ;
222+ led_busy ();
212223 return tud_control_status (rhport , request );
213224 }
214225 break ;
215226
216227 case REQUEST_SAVE_DATA :
217228 if (request -> bmRequestType_bit .direction == TUSB_DIR_OUT && request -> wLength == 4 ) {
218229 // receive into `saved_value`
230+ led_busy ();
219231 return tud_control_xfer (rhport , request , & saved_value , 4 );
220232 }
221233 break ;
222234
223235 case REQUEST_SEND_DATA :
224236 if (request -> bmRequestType_bit .direction == TUSB_DIR_IN && request -> wLength == 4 ) {
225237 // transmit from `saved_value`
238+ led_busy ();
226239 return tud_control_xfer (rhport , request , & saved_value , 4 );
227240 }
228241 break ;
229242
230243 case REQUEST_RESET_BUFFERS :
231244 if (request -> bmRequestType_bit .direction == TUSB_DIR_OUT && request -> wLength == 0 ) {
232245 reset_buffers ();
246+ led_busy ();
233247 return tud_control_status (rhport , request );
234248 }
235249 break ;
@@ -238,6 +252,7 @@ bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_requ
238252 if (request -> bmRequestType_bit .direction == TUSB_DIR_IN && request -> wLength == 1 ) {
239253 uint8_t intf_num = request -> wIndex & 0xff ;
240254 if (intf_num < 4 ) {
255+ led_busy ();
241256 // return inteface number
242257 return tud_control_xfer (rhport , request , & intf_num , 1 );
243258 }
@@ -247,6 +262,7 @@ bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_requ
247262 // Microsoft WCID descriptor (for automatic WinUSB installation)
248263 case WCID_VENDOR_CODE :
249264 if (request -> bmRequestType_bit .direction == TUSB_DIR_IN && request -> wIndex == 0x0004 ) {
265+ led_busy ();
250266 // transmit WCID feature descriptor
251267 int len = sizeof (wcid_feature_desc );
252268 if (len >= request -> wLength )
@@ -274,12 +290,7 @@ usbd_class_driver_t const* usbd_app_driver_get_cb(uint8_t* driver_count) {
274290
275291// Invoked when device is mounted
276292void tud_mount_cb (void ) {
277- blink_interval_ms = BLINK_MOUNTED ;
278- }
279-
280- // Invoked when device is unmounted
281- void tud_umount_cb (void ) {
282- blink_interval_ms = BLINK_NOT_MOUNTED ;
293+ is_blinking = false;
283294}
284295
285296// Invoked when usb bus is suspended
@@ -293,15 +304,21 @@ void tud_suspend_cb(bool remote_wakeup_en) {
293304
294305// --- LED blinking ---
295306
296- void led_blinking_task (void ) {
297- static uint32_t start_ms = 0 ;
298- static bool led_state = false;
299-
300- // Blink every interval ms
301- if ( board_millis () - start_ms < blink_interval_ms )
302- return ; // interval not elapsed yet
303- start_ms += blink_interval_ms ;
307+ void led_busy (void ) {
308+ led_on_until = board_millis () + 100 ;
309+ board_led_write (true);
310+ }
304311
305- board_led_write (led_state );
306- led_state = 1 - led_state ; // toggle
312+ void led_blinking_task (void ) {
313+ uint32_t now = board_millis ();
314+ if (is_blinking ) {
315+ if (has_expired (blink_toogle_at , now )) {
316+ is_blink_on = !is_blink_on ;
317+ blink_toogle_at = now + 250 ;
318+ }
319+ board_led_write (is_blink_on && (now & 7 ) == 0 );
320+
321+ } else if (has_expired (led_on_until , now )) {
322+ board_led_write ((now & 3 ) == 0 );
323+ }
307324}
0 commit comments