Hacker News new | ask | show | jobs
by Unklejoe 2300 days ago
I took a look at your project and I have a question.

I see that you have support for driving 16 outputs with 250 ns accuracy.

Are you using a single timer+compare unit to do this?

I struggled with this a little when I tried to do a similar project myself, but I think I came up with an algorithm that allows me to do it with one timer and one compare match register. The reason it was a little difficult was because the timers usually only have one or two compare match registers, so you can only ever have one event pending at a time. This problem would be trivial if the timer had 16/32 compare match registers.

So, you have to maintain a list of upcoming events and always be sure that the next one to occur has its value loaded in the register. There are a lot of races to watch out for (like if the time for the next event already passed before being able to load its value into the register). This requires a bunch of write-read check cycles and makes me feel uneasy.

How did you handle this?

1 comments

Thanks for your interest! I didn't want to be dependent on the number of hardware timer captures, so I did actually start with a system like you describe, with a single timer/compare and managing a linked list of upcoming events. On compare interrupt, it would iterate through any events that had passed in time, carefully setting the compare register each time to avoid potentially missing any changes. I actually thought it was pretty straightforward, but it had the effect of skewing similtaneous outputs: Each iteration cost almost a microsecond, so having 4 similtaneous changes would actually be splayed over 3.5ish uS.

Instead I am now effectively bitbanging the outputs with the dma controller. I manage a circular buffer of gpio pin changes (16 bits for "turn on", 16 bits for "turn of") for about a 128 uS window, and the DMA reads on a .25 uS interval from that buffer. There is a lot of complexity in ensuring the buffer's contents is accurate with event changes in a race-free manner, and testing that sufficiently has been where I've had to put most of my effort.