@@ -178,7 +178,48 @@ def _get_provided_nrf51_bl_version(self, flash_artifacts: List[FlashArtifact]):
178178
179179 return provided_nrf_bl_version
180180
181- def flash (self , filename : str , targets : List [Target ], cf = None , enable_console_log : Optional [bool ] = False ):
181+ def _get_boot_delay (self , cf : Optional [Crazyflie ] = None ) -> float :
182+ """
183+ Determines the boot delay for the Crazyflie.
184+ This method calculates the boot delay based on the presence of specific decks.
185+ If the AI deck is attached, a longer boot delay is used.
186+ @return: The boot delay in seconds. Returns -1 if no deck memory is found.
187+ @rtype: float
188+ @raises RuntimeError: If there is a failure in reading the decks.
189+ """
190+
191+ if cf is not None and cf .link :
192+ cf .close_link ()
193+
194+ try :
195+ with SyncCrazyflie (self .clink , cf = Crazyflie ()) as scf :
196+ deck_mems = scf .cf .mem .get_mems (MemoryElement .TYPE_DECK_MEMORY )
197+ deck_mems_count = len (deck_mems )
198+ if deck_mems_count == 0 :
199+ return - 1
200+
201+ mgr = deck_memory .SyncDeckMemoryManager (deck_mems [0 ])
202+ try :
203+ decks = mgr .query_decks ()
204+ except RuntimeError as e :
205+ if self .progress_cb :
206+ message = f'Failed to read decks: { str (e )} '
207+ self .progress_cb (message , 0 )
208+ logger .error (message )
209+ time .sleep (2 )
210+ raise RuntimeError (message )
211+
212+ if any (deck .name in ['bcAI:gap8' , 'bcAI:esp' ] for deck in decks .values ()):
213+ return 5.0
214+ except Exception as e :
215+ # If we fail to connect to the Crazyflie in firmware mode, we assume the AI-deck is attached
216+ print (f'Failed to connect to Crazyflie in firmware mode: { str (e )} . Setting boot delay to 5.0 seconds' )
217+ return 5.0 # AI-deck may be attached
218+
219+ return 0.0
220+
221+ def flash (self , filename : str , targets : List [Target ], cf = None , enable_console_log : Optional [bool ] = False ,
222+ boot_delay : Optional [float ] = 0.0 ):
182223 # Separate flash targets from decks
183224 platform = self ._get_platform_id ()
184225 flash_targets = [t for t in targets if t .platform == platform ]
@@ -276,23 +317,21 @@ def flash(self, filename: str, targets: List[Target], cf=None, enable_console_lo
276317 self .progress_cb ('Restarting firmware to update decks.' , int (0 ))
277318
278319 # Reset to firmware mode
279- self .reset_to_firmware (boot_delay = 5.0 )
320+ self .reset_to_firmware (boot_delay = boot_delay )
280321 self .close ()
281322 time .sleep (2 )
282323
283324 # Flash all decks and reboot after each deck
284325 current_index = 0
285326 while current_index != - 1 :
286327 current_index = self ._flash_deck_incrementally (deck_artifacts , deck_targets , current_index ,
287- enable_console_log = enable_console_log )
328+ enable_console_log = enable_console_log ,
329+ boot_delay = boot_delay )
288330 if self .progress_cb :
289331 self .progress_cb ('Deck updated! Restarting...' , int (100 ))
290332 if current_index != - 1 :
291333 PowerSwitch (self .clink ).reboot_to_fw ()
292- if any (deck .target in ['bcAI:gap8' , 'bcAI:esp' ] for deck in deck_targets ):
293- time .sleep (7 )
294- else :
295- time .sleep (2 )
334+ time .sleep (2.0 + boot_delay )
296335
297336 # Put the crazyflie back in Bootloader mode to exit the function in the same state we entered it
298337 self .start_bootloader (warm_boot = True , cf = cf )
@@ -321,6 +360,9 @@ def flash_full(self, cf: Optional[Crazyflie] = None,
321360 Flash .zip or bin .file to list of targets.
322361 Reset to firmware when done.
323362 """
363+ # Get the required boot delay
364+ boot_delay = self ._get_boot_delay (cf = cf )
365+
324366 if progress_cb is not None :
325367 self .progress_cb = progress_cb
326368 if terminate_flash_cb is not None :
@@ -336,7 +378,7 @@ def flash_full(self, cf: Optional[Crazyflie] = None,
336378 info_cb (self .protocol_version , connected )
337379
338380 if filename is not None :
339- self .flash (filename , targets , cf , enable_console_log = enable_console_log )
381+ self .flash (filename , targets , cf , enable_console_log = enable_console_log , boot_delay = boot_delay )
340382 self .reset_to_firmware (boot_delay = 5.0 )
341383
342384 def _get_flash_artifacts_from_zip (self , filename ):
@@ -549,7 +591,7 @@ def console_callback(self, text: str):
549591 print (text , end = '' )
550592
551593 def _flash_deck_incrementally (self , artifacts : List [FlashArtifact ], targets : List [Target ], start_index : int ,
552- enable_console_log : Optional [bool ] = False ):
594+ enable_console_log : Optional [bool ] = False , boot_delay = 0.0 ):
553595 flash_all_targets = len (targets ) == 0
554596 if self .progress_cb :
555597 self .progress_cb ('Identifying deck to be updated' , 0 )
@@ -604,10 +646,7 @@ def _flash_deck_incrementally(self, artifacts: List[FlashArtifact], targets: Lis
604646 self .progress_cb (f'Updating deck { deck .name } ' , 0 )
605647
606648 # Test and wait for the deck to be started
607- if any (deck .name in ['bcAI:gap8' , 'bcAI:esp' ] for deck in decks .values ()):
608- timeout_time = time .time () + 9
609- else :
610- timeout_time = time .time () + 4
649+ timeout_time = time .time () + 4. + boot_delay
611650 while not deck .is_started :
612651 if time .time () > timeout_time :
613652 raise RuntimeError (f'Deck { deck .name } did not start' )
@@ -634,10 +673,7 @@ def _flash_deck_incrementally(self, artifacts: List[FlashArtifact], targets: Lis
634673 continue
635674
636675 # Wait for bootloader to be ready
637- if any (deck .name in ['bcAI:gap8' , 'bcAI:esp' ] for deck in decks .values ()):
638- timeout_time = time .time () + 9
639- else :
640- timeout_time = time .time () + 4
676+ timeout_time = time .time () + 4. + boot_delay
641677 while not deck .is_bootloader_active :
642678 if time .time () > timeout_time :
643679 raise RuntimeError (f'Deck { deck .name } did not enter bootloader mode' )
0 commit comments