Here we go then… beta 2 (zip file in the first post).

Changes since beta 1.

  • (breaking) No more II op. Don’t do II WW.PRESET 1, instead just do WW.PRESET 1
  • (breaking) No more UNMUTE, instead use MUTE x to get the status of the mute on input x, and MUTE x y to set the mute on input x (y = 0 to disable mute, y = 1 to enable mute).
  • Rewritten key bindings.
  • 16 history entries in live mode instead of 6.
  • Global cut and paste between live, edit, and preset write modes.
  • <esc> key handling changed. No more getting stuck between preset write and preset read mode (this always happened to me anyway).
  • Limited script recursion (max recursion depth is 8) including self recursion.
  • No more leading spaces before : and ;

Please look at the new key bindings, the major changes are no more ~ key to enter pattern mode. Mode changes are only done using <tab>. I will admit it took me a bit of time to get used to that and I’m not sure if it’s the right choice or not. But please, before you raise pitchforks about it give yourself a bit of time to get used to it.

The help menu is now on <print screen>.

F1 though F10 trigger scripts, and you can use an alt modifier to jump to edit that script.

I’ve switched to using alt and win to describe the keyboard shortcuts rather than using the technically more correct meta as that’s what printed on the keyboard.

Some keybindings may be missing. Toggling mutes from the keyboard definitely is. Suggestions for what it should be?

(There was a typo in the keybinding docs, F9 is the metro script, F10 is the init script, docs updated now.)


GitHub tells me that I’ve changed 59 files and made 3,593 additions and 2,890 deletions since beta 1. :dizzy_face:

@tehn I’d like to put a PR in for this, even if I’ve still got some more stuff I’d like to get done for the release. Cool?

10 Likes

yes to a PR! amazing!!

1 Like

there is no reason for that to be static. IMO it’s a mistake.

as it happens, there’s no race condition because all the soft-timer callbacks are always called from a single timer interrupt, and avr32 interrupts aren’t nested unless the handler explicitly re-enables the IRQ.

i see that i made the same mistake in the bees encoder-polling handler. (similarly without consequences.) maybe it was copied from there.

as to the reason for this (anti-)pattern, it’s something i used to see a lot in embedded C code in days past, on much more limited systems. for an extremely hot ISR on (say) 8051, it was actually a good idea to minimize stack allocation. stupid habit now.

3 Likes

So by avoiding using the stack in an ISR we avoid having to push and pop the stack address register on the context switch?

I found an interesting article on the ARM website about interrupt latency, it’s a bit ‘wow ARM CPUs are amazing’, but an interesting read nonetheless. I also think ARM Cortex chips have 2 stack pointer registers to make context switches cheaper. I’m guessing many modern CPUs use similar tricks.

does this update preserve numpad functionality? i wonder if i’m the only person that uses it…

Does this release takes over @tehn Teletype V2 proposal? I understand they are 2 different firmware but does this means that this version kind of defacto supersedes that proposal?

mm… TBH, i am not totally sure now. it gets a bit confusing.

had a quick look at the avr32 architecture manual again; AVR32B (which teletype uses) has low-interrupt-latency features; from section 1.3.2:

implements dedicated registers to hold the status register and return
address for interrupts, exceptions and supervisor calls. This information does not need to be written to the stack, and latency is therefore reduced. Additionally, AVR32B allows hardware shadowing of the registers in the register file. The INT0 to INT3 contexts may have dedicated versions of the registers in the register file, allowing the interrupt routine to start executing immediately.

aleph uses UC3A, which doesn’t have those features, and saves SR, etc. on the system stack, the old-fashioned way. (there is still a dedicated shadow register for SP, only accessible by privileged modes… this is the confusing bit for me.) if you’re going to get a stack overflow, it is likely to be in an ISR, so it’s not totally crazy to avoid stack allocations in them. i doubt it will impact performance sigificantly, at least on UC3B, but it would be interesting to try to time it (by scoping a GPIO interrupt, say) and to look at the objdumps…

bottom line is i think it’s safer as you say to use local stack variables and avoid the possibility of race conditions; the hypothetical ISR latency improvement is probably not worth it.

(sorry for this minor derailment of the thread, we could move the topic somewhere else)

It does (but I don’t have the ability to test it), the key bindings docs should be exhaustive, they were made by going through the code. Do you use it with a standalone numpad?

This will be the next official firmware. The V2 features can still be implemented on top of this, though I think it would probably be wise to revisit them (e.g. was the primary use of timelines a way to allow longer scripts, and if so, do the sub commands meet the same aim?).

From what I can tell the 2 shadow SP registers, called MSP and PSP on ARM chips (main stack pointer and privileged stack pointer), along with the very limited memory protection available enable you to have supervisor code that can’t be interfered with by unprivileged code (useful for say, FreeRTOS).

I agree too. I’ll definitely change the ones in the teletype code base, I may change the ones in init_teletype.c too.

3 Likes

How about using with 1 - 8 to toggle mute/unmute for the trigger inputs? Haven’t done the update yet cause I did not succeed in saving my scenes to USB by now but I will definitely miss this feature.

Anyway, thanks for doing all the work - I am really looking forward to a lot of the new features!

Just a quick heads up, there is a bug in beta 2, where preset saving only saves script 1 to flash. Fix incoming.


Beta 3 available on the first post with fix.


FYI I’ve noticed another bug, the bar at the top of the screen in live mode doesn’t always display. I’ve fixed it already, and that fix will be in the next beta.

I’m seeing the same screen artifacts that @Leverkusen reported when I’m switching modes. It will happen for a few seconds and then correct itself.

I’m also experiencing a save/load or scene change bug (not sure which). I have the default TT scripts on a USB stick. I just loaded them back onto my TT now that this version was more stable for me. If I load Triangle Mountain and then switch to 4Track, it keeps the tracker data from T.Mountain and doesn’t load the 4 lanes saved with 4Track.

1 Like

I think I might know what’s causing that. Does it end up only loading the data from pattern 0, but patterns 1, 2 & 3 stay the same? You might find that you get the same thing with both USB loading/saving and preset loading/saving.

I’ll get it fixed tomorrow most likely. Then I’ll release a new beta with the fix and the new i2c code included too.

3 Likes

Yep! Pattern 0 loads correctly, but 1, 2, and 3 are always blank.

1 Like

Beta 4 posted in the first post.

Changes since beta 3.

  • Switch the metro script (and delayed commands) to running at the next available opportunity, rather than immediately. See this post and onwards for details as to why. The downside is that the metro clock may be a bit more jittery depending on system load. The upside is that i2c / II crashes are significantly reduced if not eliminated entirely… (famous last words…)
    Enormous thanks to @trickyflemming for all the testing he did as well as @tehn for coming up with the solution and @Leverkusen for his testing too.
  • Fix the pattern saving bug that @trickyflemming reported. Annoyingly the cause was the same as the script saving bug that necessitated beta 3.
  • Make sure that the activity bar in live mode always displays.

There are also some underlying changes to how II messages to the original trilogy modules are calculated, I’ve tried my hardest to check the values are correct, but due to my development setup it’s not that easy to check on actual hardware. I would appreciate feedback to make sure the II messages still work (and remember you don’t need to use the II op anymore).

Assuming there aren’t any major bugs I will get a PR in for this code this weekend… and then onto sorting out the USB memory stick issues.

6 Likes

Sam,

I appreciate your work on this very much and am currently trying out the new firmware - thanks a lot for all the afford you are dedicating to this!

There is just one thing I am not sure about. That is the new triple switch to change between tracker view, live view and edit view. I used to switch from edit view to live view back and forth to just change global values as the metro speed, single trigger pulse widths or the es.mode without looking on the screen - just a short press, typing something like M 100 and switching back to work on the script. Now I am constantly overwriting the pattern when I automatically do so and have to look on the screen where I am which is a bit cumbersome.

I understand live and edit modes as two sides of teletype functionality where it makes sense to switch between but the tracker view is somehow a different thing plus triple switching seems counter intuitive to me as you cannot do it blind.

Is there a special reason for the new method? Would you consider the old way coming back some day?

Thanks again for the great support,

Sven

btw: at a first glance i2c seems good with reading cycles and triggering non existing trigger.outs with a metro script and trigger input…:heart_eyes:

2 Likes

The original discussion about changing the live/edit/pattern shortcuts starts here:

And then this is what I wrote about it when I released beta 2 (which included the updated key bindings):

I still stand behind the, ‘please give it some time’ bit.

I do have some other ideas for what to do to solve the issue from a different angle, but they’re not quite fleshed out yet. I also think that muscle memory takes a few days to shift, so it’s worth trying to live with it for a while.

Thanks! The new beta fixed the tracker loading for me.

I just found another weird, minor bug. The up/down arrow keys seem to be sent simultaneously to the tracker view and the load screen view.

  1. Load a scene with a description long enough to require scrolling.
  2. Go to the tracker view.
  3. Hit Esc. to bring up the scene description.
  4. Use the down arrow to scroll the description.
  5. Hit Esc. to go back to tracker view. The tracker will now be scrolled a number of steps down.

If I hit Esc again, the description will have scrolled back to the top. If I hit Esc. yet again, the tracker will then be back at the top.

Another bug report (sorry!)

I’m not sure how long it’s been like this, but the factory default 4Track script isn’t working as intended. F5 is supposed to advance all four tracks, but it is only advancing the first track. The gate outs are responding correctly, though.

Can you post the contents of script 5 for me? I’m afraid I won’t be able to look at the bugs till Friday at the earliest now.


edit: managed to sneak a quick look before breakfast, I’ve found the script. I think there may be something odd going on with P.HERE / P.NEXT, etc. It probably happened when I created the PN versions of all the P ops.

I’ve also noticed another small bug with live mode, where it doesn’t always clear the output of the previous command.

Also, just noticed a much more serious bug with multiple commands (i.e. using ;)

Right this bug wasn’t too bad, but a bit obscure. Consider the following statements in live mode (this might be a bit beyond you if you don’t understand the theory behind the Teletype’s programming language):

X 5
Y 7
X; Y

One would expect that the final statement will just print out the value of Y. In fact nothing is displayed and the value of Y has changed to 5!

What’s happening is that first sub command X; adds the value 5 to the command stack, the second sub command Y, sees that there is a single value on the command stack and assumes that it should set the value of Y to it, rather than retrieve the current value of Y.

The solution is fairly straightforward, just reset the command stack between sub commands.


Next up the far more annoying bug, which caused @trickyflemming’s weird scrolling bug, amongst many other weird things. See here for the technical details.

@tehn and @zebra I’ve added -fno-common to the compiler flags to catch ambiguous declarations (i.e. global variables where the compiler is trying to infer if they should be extern or static). These leads to errors with the following variables:

init_teletype.h

  • tcTicks
  • tcOverflow

I propose the following change to make them both static in init_teletype.c only. (The same issue also in init_ansible.h and init_trilogy.h.)

--- a/src/init_teletype.h
+++ b/src/init_teletype.h
@@ -4,8 +4,4 @@
 #include "types.h"
 
-// global count of uptime, and overflow flag.
-volatile u64 tcTicks;
-volatile u8 tcOverflow;
-
 extern void register_interrupts(void);
 extern void init_gpio(void);
--- a/src/init_teletype.c
+++ b/src/init_teletype.c
@@ -23,6 +23,6 @@
 //----- variables
 // timer tick counter
-volatile u64 tcTicks = 0;
-volatile u8 tcOverflow = 0;
+static volatile u64 tcTicks = 0;
+static volatile u8 tcOverflow = 0;
 static const u64 tcMax = (U64)0x7fffffff;
 static const u64 tcMaxInv = (u64)0x10000000;

kbd.h

  • old_frame

Again, I propose to make it static in kbd.c.

--- a/src/kbd.h
+++ b/src/kbd.h
@@ -50,6 +50,4 @@
 
 
-s8 old_frame[8];
-
 extern u8 hid_to_ascii_raw(u8 data);
 extern u8 hid_to_ascii(u8 data, u8 mod);
--- a/src/kbd.c
+++ b/src/kbd.c
@@ -4,4 +4,5 @@
 #include "kbd.h"
 
+static s8 old_frame[8];
 
 bool frame_compare(u8 data) {

edit 2017-04-22: I’ve made these changes on my libavr32 branch. I will post a PR soonish.

2 Likes