Very nice indeed. Managing 32 PWM levels on a 4*5 matrix completely in software is impressive. And a good refresh rate as well.
Code wise, I like the way you lay it out, especially the comments. I hate the recent trend of putting comments within a procedure and in the code space ( and on every other line). Your full width comments before and right side comments during a procedure (and initialisation) should be mandatory.
I also like the neatness of the end_of_period and end_of_cycle checks. I'm assuming that you couldn't find a way to avoid the asm - the shift at end_of_period looks like it should be C able.
The only thing I can see that isn't required is the clearing of PIE1.
Overall an excellent example. A++.
Mike.




