Open stephenhensley opened 2 years ago
Is there already a method for printing to serial in libDaisy?
Then we simply need to add a printHook() function to the Heavy context that uses this.
From what I can tell this would be done via the hardware.PrintLine()
function, correct?
Ok I got a PoC working! Add this to the generated .hpp:
void StartLog()
{
som.StartLog();
}
void PrintLine(const char* format)
{
som.PrintLine(format);
}
And then this to the main .cpp:
static void printHook(HeavyContextInterface *c, const char *printLabel, const char *msgString, const HvMessage *m);
...
hardware.StartLog();
hv.setPrintHook(printHook);
...
static void printHook(HeavyContextInterface *c, const char *printLabel, const char *msgString, const HvMessage *m)
{
char buf[64];
char *dst = buf;
int len = strnlen(printLabel, 48);
dst = stpncpy(dst, printLabel, len);
dst = stpncpy(dst, " ", 1);
dst = stpncpy(dst, msgString, 63-len);
hardware.PrintLine(buf);
}
We then get our serial device and the test-patch prints to the console:
Only thing is there is some noise appearing on the oled of my Field, but I'm sure there is some tricks to suppress that.
@stephenhensley Is this something you think we should enable by default or should there be a flag in the board json to enable it?
Ah and we can simply address these functions as hardware.som.StartLog()
and hardware.som.PrintLine()
so we don't even need to modify json2daisy for this.
I just need an OK for the printHook()
code and I can add it to HVCC for the next release.
~Seems this doesn't work if we use size optimized linking, which results in a broken program.~
Nevermind, I was not doing my manual commands right and didn't flash the bootloader correctly.
@dromer
Exciting stuff!
I'm not sure if it should always be on or not. I think the CPU usage for it when it's not actively being used is fairly minimal, but I haven't done a ton of profiling of that specifically. Generally, I do prefer the ability to enable/disable things when they have an effect on program size, or runtime performance
Also, FWIW it may simplify things (or it may not) to know that there are some template static class methods for the Logging class that might be useful in this context, although all of the existing Daisy SOMs do currently have a logger method with wrappers. So your approach should work as is.
e.g.
daisy::Logger<LOGGER_INTERNAL>::StartLog();
daisy::Logger<LOGGER_INTERNAL>::PrintLine("Hello World");
Only other thing to keep an eye on is printing float values. There's a section at the bottom of this page in the libDaisy docs that covers the three ways to deal with that with the logger class. The "easiest" method lets you print floats normally, but adds a fair amount to the program size.
@stephenhensley Well .. nearly!
I actually don't know anything about C++ templates so I don't think this makes it any easier for me ;)
Trying a simple patch to send a number, which should come in as characters via msgString
, however somehow I get nothing and it just sends an empty message with just the printLabel
part.
Relevant code that is used to send the print and format the message: https://github.com/Wasted-Audio/hvcc/blob/develop/hvcc/generators/ir2c/static/HvControlPrint.c https://github.com/Wasted-Audio/hvcc/blob/develop/hvcc/generators/ir2c/static/HvMessage.c#L159-L199
@stephenhensley Ah yes, if I add LDFLAGS += -u _printf_float
to the build then the built-in string formatting works.
This does increase program memory slightly, but I expect the vast majority of programs to want to use size optimized builds anyway to be honest.
I've updated the PR to make this optional from the meta file. We can then add a flag to the plugdata compile dialogue where the user can enable such "debug printing" when they require it.
Requested feature, and an interesting one at that.
Not sure how we'd manage any string formatting that goes a long with it, but if pd messages work like max messages than we could just parse the messages as strings and schedule them for output periodically.