My plan to support multiple brightness levels has been to run the ISR a multiple number of times faster. For example, if I want 100 Hz refresh and have 8 rows, that would be 800 Hz with a single brightness. If I want 8 levels of brightness, I would run it at 6400 Hz and then the ISR would look at the brightness level and decide which of those 8 extra cycles it should turn off the row, then every 8 cycles it would go on to the next row. I'm not saying that is the best approach, but I've used it and it works. Besides the inefficiency of the extra ISR cycles, you just can't get too many levels of brightness and forget about gamma adjusting them.
So this takes me to the second idea which I've tried with some success. Instead of having evenly sliced slots, adjust the time so that it turns at the time to turn off the row and then delay the proper time to enable the next row. So now you don't have 8 times the cycles for 8 levels or brightness, but only 2 cycles. I tried this with a compare match and was pushing it ahead the X cycles I wanted, but as long as the timer is running fast enough such as a 16 bit timer running at clk/1, you might have 10000 cycles to work with. We can easily then pick between returning at 8000 cycles or 8020 cycles. This gives the granularity to do gamma correction, but there is one issue when I was testing it. If you are trying to do a small amount (like the lowest settings which when gamma) you run into only a few cycles. If you push ahead the compare match only a few cycles then you probably have already missed it. That was as far as I got with the testing. Clearly you can't let the on cycles vs off cycles get too small. Then I thought about testing the amount and just waiting in the ISR for a small number of cycles like less than 50 or so, but that seems like a kludgy ugly solution.
So...what ideas do you guys have for multiplexing with some granular control over how many cycles it is on vs. how many cycles it is off. Would an approach of using two compare matches solve the too small problem? Is there a better way all together to do it?
I'm going to be implementing this on a mega4809 and it has additional interrupt features if those open up any new ideas too.