-
Notifications
You must be signed in to change notification settings - Fork 34
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
usb device lua REPL #8
Comments
this is working on a very basic level.
takes around 20 seconds before the 'AT' commands settle (we can work around this in future). should print 'Dialing...' while it's waiting. then 'welcome to crow' and a '>' prompt once it's ready. try @tehn i don't fuly grasp what you mean about returning a directly executable command to the host. this means we'd allow a crow script to directly execute lua code in a norns environment? this feels like an extension on the basics, so i think it should become a new issue if there's a specific use case you have in mind. i can see the value as a simple 'getter' though i guess. |
holy moly!!!! what i (think i) meant is for crow to be able to return actual text like:
and norns would have a function i need to think more about the interaction between the two systems based on the parameters and features we're anticipating. since we last spoke i've had to think wayyy more about callbacks etc while hacking norns. so we need to figure out how to process incoming serial (coming out of crow). if it's just a REPL, we need to know, for example, when the data coming in is the return of a getter or poll. ie: (i've added a
make sense? so on the norns side (or whatever interface side) it can look for string token of course another way to do this would just be keyed values ie _c(RET_CV, 1, 1.0) and then make a parser, which would maybe make it easier to interface with non-lua clients. but i sortof love the idea of just writing callbacks ie on norns
in the crow code above,
of course instead of sorry for the working-it-out-as-i-go |
for reference i just ran the first part, and we're partly there:
clearly i'm missing most of the error messages, but that shouldn't be too bad. not sure if the repl should be able to query the value of variable without having to explicitly print. can you clarify that
and that should be able to be called inline in your lua script (hopefully without blocking?). seems uncomfortable to query a value and have to setup a callback to receive it. could use coroutines or continuations behind the scenes to have fake-threading if needed. //
i think we should write some more examples of what the potentials polls are before thinking of a communication protocol. first we need a very clear picture of what and how to introspect into the crow system. |
to me the problem with:
is that it's an asynchronous system. having the norns or whatever host explicitly wait for communication is a bad idea (hence your suggestion for coroutines, which i've still never investigated fully). but also it requires setting up some sort of state machine. ie, norns/etc has to know that the next incoming value is something that should be treated a certain way. normally it's just print it (?) but in this case it'd have to use it for an assignment/etc. i don't want to have to write a complicated interpreter... i mean i'm even trying to avoid keeping track of KEY values for a serial protocol :) what i think i'm trying to design is a way to both maintain REPL functionality and at the same time add an interpreter layer that another process (norns/m4l/etc) can interact with. so the
ohh yes indeed! this is all very exciting |
i just realized that i was being quite dense about the use case you were describing with the getters & setters. i've been thinking pretty exclusively about writing on crow scripts, and thinking of the repl as a way to prototype that code. in this way i didn't correctly separate that your proposed method was for 2 systems communicating remotely. reading above i knew you were talking about this but the ramifications weren't following all the way through. especially when thinking about crow as an extension to norns, it feels very natural to define callbacks in the crow system, that the user then implements in their norns script. we should structure the code / have some facility to have crow shoot all of it's callback definitions to norns upon query (or perhaps user-defined callbacks are sent at script start). this could be done with optional functions that a user can include for such purposes. of course the repl is a big help here too. i will leave the question unanswered of exactly how the user interacts with the crow-repl (vs the matron-repl), but i think making the process as interactive as possible is great. i did some initial RAM tests and i'm confident we have nothing to worry about in terms of having things be self-documented on crow, and queryable via helper functions in the repl. // back to the topic, my distinction is that on crow itself (and thus, via the crow-repl as it is running on crow itself), the user should be able to query a value directly, which will fetch the value from the C slope generation class. this makes it possible to take a more functional approach without needing to explicitly store state. as such it's possible for an envelope generator to take a function which returns the current value of an input when it's called. see lua/crowlib.lua in the this can be thought of as a 'stream' (or 'poll') set to the maximum rate, which saves the current input value to a variable called // using crow as a hardware extension to a host, vs using a remote host to control crow through repl or by writing a script. naturally your focus will likely be more on the former (hence the great callback declaration idea above), while mine is more on the standalone functionality. //
i got tired of rambling and so spent some time fixing issues in the asl module which is now running on the chip and happily lfo-ing up and down. there's certainly issues in the slope generating code (it seems to wander out of range), but at least that's a nicely isolated problem. but also! i just added the 'get_cv(channel)' function you sketched out and it works just fine. obviously the implementation is dead easy on crow, so we can feel free to rework that as time goes on. also in implementing this i realized how it's far more difficult than i thought to have the call return the value directly. all crow can ever send back is text. it is a repl after all, and the only pieces on the remote host are the Read and Print. so any inline approach feels bizarre & would require a parser inside each getter which seems way overkill and predisposed to all kinds of errors. the more i write lua the more it feels truly wacky and capable of all kinds of ridiculous things. |
ack, i should've been more explicit.
this is absolutely correct and the right way to do things, as you propose. i'm wondering how to design the two use cases together. for one thing, it'll be easy to have a i'll revisit the command list and consider this, but would be curious to hear your opinions. more broadly: crow use cases.crow as remotei suspect this will be the prominent use case as
particularly because there will pre-made scripts and patches that people can just use without learning to script anything (unfortunately this is the market at large). re: matron REPL integration. i don't plan on implementing some special mode as i don't think it's necessary. given the
so in effect, the crow and norns REPLs will be fully integrated together just by the nature of the communication scheme. you can always just so, crow is not just a cv interface, but a remote lua. we need to figure out multi-line input, for sending a full function over. i'm not sure how even the normal command line REPL does this actually, in terms of understanding completion. crow as localprimary access will be likely via a command line util (like screen, but with readline and some minor interfacing help, as mentioned on another git issue).
and then there's upload-to-flash, which is different than just putting a file into working memory. this is where we'll need a state switch at the C level: serial to input is normal REPL mode. serial to flash is just taking incoming bytes and writing them to the lua program memory space, which will persist on power-down. entering/exiting serial-to-flash mode should be interactive, ie. when in flash mode the flash-writing function should check for a token ie the REPL command line util will wrap the file in this start/stop condition. after a write-to-flash the LVM should reset fully (clear memory) and start back up, executing the flash mem. of course, given this approach it'd be very simple to write a crow-script "librarian" that actually runs on norns itself-- if one simply wanted to attach the crow to norns to flash a new crow script. in general, i think the common use for crow-as-remote will not be to have crow running custom code in addition to the standard library. ie, no real need to define an onboard callback if there is already a to-remote-callback which means the callback can be implemented on the host (norns/m4l) instead. for example... having extra metros running onboard the crow, instead of metros locally on norns/m4l. we'll need some sort of command for remote mode, the norns helper oh man, no filter on this ramble, i'm sorry. need to categorize this all. |
repeating this for emphasis
in general agree with all you've written. i've implemented stubs for the
i was thinking the parser for switching serial stream destination would also check for a _goto_bootloader command, but if we have a _set_default_flash or similar command, this shouldn't be necessary, as the user can kill a non-behaving script. for error checking i was thinking we stream serial to RAM buffer, restart the lua VM, and run loadstring() on the new program. then we run a simple lua program that tests the system is functioning (and not eg. in an infinite loop), which can timeout (resulting in error condition), or succeed, causing the program to be written to flash. before running loadstring we could run a checksum which the command-line util would send at end of each upload. i believe stm32 has an on-board MD5 (or similar) calculator so this shouldn't be difficult to implement. i'm uncertain how reliable we can anticipate the serial communication to be. a simpler approach would be to have a failed upload simply retry once, and error out after second attempt. // in terms of the io between norns & crow, i think the approach you outlined is perfect. both systems send raw strings which can optionally be executed if the serial stream is prefixed with the ^^ symbol.
side note: understood that the remote use case is likely far more typical, and agreed that predefined functionality is of utmost importance. of course i will continue to pursue these ideas more personally, but i want to prioritize making the typical use case as solid as possible. i'm hoping the majority of these simple norns & max/m4l functions can be made simultaneously accessible via the default script. this default script will ship in the binary itself, not in user-lua-space, so we can always jump to it. i will spend some time thinking about those remote use-cases, perhaps more from the max/m4l side (leaving norns to you) so we can get closer to a command list that can be implemented. also agreed doing callbacks on the host system makes most sense majority of the time. typically crow timers will be used for internal things like executing polls that have been requested by the host (eg get_adc) |
oh oh i want to emphasize that i'm very interested in both use cases! what is fun is to figure out how to make both work alongside one another seamlessly and elegantly, and it think the design feels good! |
fully functioning usb device REPL:
connect via screen/minicom
type directly at crow, receive evaluations
two types of messages received from crow: DEBUG and COMMAND. one or the other could simply have a preceding character, ie, debug starts with
>
for example. a command would be something that could be directly executed by the host interpreter, ieadc(1,2)
investigate end character (newline?) to evaluate
note screen/minicom will need to turning local key echo on?
The text was updated successfully, but these errors were encountered: