@@ -104,11 +104,11 @@ env_opts() ->
104104 #{
105105 path => os :getenv (
106106 " ATOMVM_REBAR3_PLUGIN_PICO_MOUNT_PATH" ,
107- get_default_mount ( )
107+ os : getenv ( " ATOMVM_PICO_MOUNT_PATH " , " " )
108108 ),
109109 reset => os :getenv (
110110 " ATOMVM_REBAR3_PLUGIN_PICO_RESET_DEV" ,
111- get_reset_base ()
111+ get_reset_dev ()
112112 )
113113 }.
114114
@@ -123,78 +123,103 @@ get_stty_file_flag() ->
123123 end .
124124
125125% % @private
126- get_reset_base () ->
126+ get_reset_dev () ->
127127 {_Fam , System } = os :type (),
128128 Base =
129129 case System of
130130 linux ->
131- " /dev/ttyACM* " ;
131+ filelib : wildcard ( " /dev/serial/by-id/usb-Raspberry_Pi_Pico_????????????????-if00 " ) ;
132132 darwin ->
133- " /dev/cu.usbmodem14*" ;
133+ Bin = darwin_ioreg :pico_callout_devices (),
134+ lists :foldl (fun (Path , Acc ) -> [binary_to_list (Path ) | Acc ] end , [], Bin );
134135 _Other ->
135- " "
136+ []
136137 end ,
137138 os :getenv (" ATOMVM_PICO_RESET_DEV" , Base ).
138139
139- % % @private
140- get_default_mount () ->
140+ % %% @private
141+ find_mounted_pico () ->
141142 {_Fam , System } = os :type (),
142- Default =
143+ Wildcard =
143144 case System of
144145 linux ->
145- " /run/media/" ++ os :getenv (" USER" ) ++ " /RPI-RP2" ;
146+ " /run/media/" ++ os :getenv (" USER" ) ++ " /{ RPI-RP2,RP2350} " ;
146147 darwin ->
147- " /Volumes/RPI-RP2" ;
148+ " /Volumes/{ RPI-RP2,RP2350} " ;
148149 _Other ->
149150 " "
150151 end ,
151- os :getenv (" ATOMVM_PICO_MOUNT_PATH" , Default ).
152+ case filelib :wildcard (Wildcard ) of
153+ [Pico | _ ] = Path ->
154+ rebar_api :debug (" Found pico device, using ~p from devices list: ~p " , [Pico , Path ]),
155+ {ok , Pico };
156+ _ ->
157+ not_found
158+ end .
152159
153160% % @private
154161wait_for_mount (Mount , Count ) when Count < 30 ->
155- try
156- case file :read_link_info (Mount ) of
157- {ok , # file_info {type = directory } = _Info } ->
158- ok ;
159- _ ->
160- timer :sleep (1000 ),
161- wait_for_mount (Mount , Count + 1 )
162- end
163- catch
164- _ ->
165- timer :sleep (1000 ),
166- wait_for_mount (Mount , Count + 1 )
162+ case Mount of
163+ " " ->
164+ case find_mounted_pico () of
165+ not_found ->
166+ timer :sleep (1000 ),
167+ wait_for_mount (Mount , Count + 1 );
168+ {ok , Pico } ->
169+ case file :read_link_info (Pico ) of
170+ {ok , # file_info {type = directory } = _Info } ->
171+ {ok , Pico };
172+ Err ->
173+ rebar_api :abort (" Pico mount point is not a directory (~p )" , [Err ])
174+ end
175+ end ;
176+ Path ->
177+ case file :read_link_info (Path ) of
178+ {ok , # file_info {type = directory } = _Info } ->
179+ {ok , Path };
180+ _ ->
181+ timer :sleep (1000 ),
182+ wait_for_mount (Mount , Count + 1 )
183+ end
167184 end ;
168- wait_for_mount (Mount , 30 ) ->
169- rebar_api :error (" Pico not mounted at ~s after 30 seconds. giving up..." , [Mount ]),
170- erlang :throw (mount_error ).
185+ wait_for_mount (_Mount , 30 ) ->
186+ rebar_api :abort (" Pico not mounted after 30 seconds. giving up..." , []).
171187
172188% % @private
173- check_pico_mount (Mount ) ->
174- try
175- case file :read_link_info (Mount ) of
176- {ok , # file_info {type = directory } = _Info } ->
177- rebar_api :debug (" Pico mounted at ~s ." , [Mount ]),
178- ok ;
179- _ ->
180- rebar_api :error (" Pico not mounted at ~s ." , [Mount ]),
181- erlang :throw (no_device )
182- end
183- catch
184- _ ->
185- rebar_api :error (" Pico not mounted at ~s ." , [Mount ]),
186- erlang :throw (no_device )
189+ get_pico_mount (Mount ) ->
190+ case Mount of
191+ " " ->
192+ case find_mounted_pico () of
193+ not_found ->
194+ rebar_api :info (" Waiting for an RP2 device to mount..." , []),
195+ wait_for_mount (Mount , 0 );
196+ {ok , Pico } ->
197+ {ok , Pico }
198+ end ;
199+ Path ->
200+ case file :read_link_info (Path ) of
201+ {ok , # file_info {type = directory } = _Info } ->
202+ rebar_api :debug (" Pico mounted at ~s ." , [Mount ]),
203+ {ok , Path };
204+ _ ->
205+ rebar_api :info (" Waiting for the device at path ~s to mount..." , [
206+ string :trim (Mount )
207+ ]),
208+ wait_for_mount (Mount , 0 )
209+ end
187210 end .
188211
189212% % @private
190- needs_reset (ResetBase ) ->
191- case filelib : wildcard ( ResetBase ) of
213+ needs_reset (ResetDev ) ->
214+ case ResetDev of
192215 [] ->
193216 false ;
194217 [ResetPort | _T ] ->
195218 case file :read_link_info (ResetPort ) of
196219 {ok , # file_info {type = device } = _Info } ->
197220 {true , ResetPort };
221+ {ok , # file_info {type = symlink } = _Info } ->
222+ {true , ResetPort };
198223 _ ->
199224 false
200225 end ;
@@ -208,7 +233,7 @@ do_reset(ResetPort) ->
208233 BootselMode = lists :join (" " , [
209234 " stty" , Flag , ResetPort , " 1200"
210235 ]),
211- rebar_api :debug (" Resetting device at path ~s " , [ResetPort ]),
236+ rebar_api :info (" Resetting device at path ~s " , [ResetPort ]),
212237 ResetStatus = os :cmd (BootselMode ),
213238 case ResetStatus of
214239 " " ->
@@ -259,31 +284,29 @@ get_uf2_appname(ProjectApps) ->
259284 binary_to_list (rebar_app_info :name (App )).
260285
261286% % @private
262- do_flash (ProjectApps , PicoPath , ResetBase ) ->
263- case needs_reset (ResetBase ) of
287+ do_flash (ProjectApps , PicoPath , ResetDev ) ->
288+ case needs_reset (ResetDev ) of
264289 false ->
265- rebar_api :debug (" No Pico found matching ~s ." , [ResetBase ]),
290+ rebar_api :debug (" No Pico reset device found matching ~s ." , [ResetDev ]),
266291 ok ;
267292 {true , ResetPort } ->
268293 rebar_api :debug (" Pico at ~s needs reset..." , [ResetPort ]),
269294 do_reset (ResetPort ),
270- rebar_api :info (" Waiting for the device at path ~s to settle and mount..." , [
271- string :trim (PicoPath )
272- ]),
295+ rebar_api :info (" Waiting for the device at path ~s to settle and mount..." , [PicoPath ]),
273296 wait_for_mount (PicoPath , 0 )
274297 end ,
275- check_pico_mount (PicoPath ),
298+ { ok , Path } = get_pico_mount (PicoPath ),
276299 TargetUF2 = get_uf2_file (ProjectApps ),
277300 App = get_uf2_appname (ProjectApps ),
278301 File = App ++ " .uf2" ,
279- Dest = filename :join (PicoPath , File ),
280- rebar_api :info (" Copying ~s " , [File ]),
302+ Dest = filename :join (Path , File ),
303+ rebar_api :info (" Copying ~s to ~s " , [File , Path ]),
281304 case file :copy (TargetUF2 , Dest ) of
282305 {ok , _Size } ->
283306 ok ;
284307 CopyError ->
285308 rebar_api :error (" Failed to copy application file ~s to pico: ~s " , [File , CopyError ]),
286309 erlang :throw (picoflash_copy_error )
287310 end ,
288- rebar_api :info (" Successfully loaded ~s application to device at path ~s ." , [App , PicoPath ]),
311+ rebar_api :info (" Successfully loaded ~s application to the device ." , [App ]),
289312 ok .
0 commit comments