Wacky pasm problem
andrewsi
Posts: 59
I spent most of today fighting with my first mildly complex pasm routine, and encountered a problem I just couldn't solve, although I ultimately did work around it with what was probably a superior solution anyway.
The project is a simple LED matrix controller, although it's an 8x8 common cathode rgb matrix from Sparkfun, so it's got a bit more wiring than an ordinary single color unit. It's wired up through 32 bits worth of serial shift registers, which form a long, divided into four bytes of Row/red/green/blue. Row is a bit mask, one bit per row, and the rgb bytes are masks for those colors in their respective columns. Being a common cathode matrix, I am cycling through the rows so only one bit is set in the row byte at a time, while any arbitrary rgb colors are set in the columns for that row. Repeated shifting out of the full 32 bits, one line at a time, basically turns this into tv-style raster scanning. I imagine this is fairly conventional.
Anyway- the purpose of the pasm routine is to read a main memory frame buffer defining rgb pixels (upper byte wasted) with rgb values from 0 to $ff, defining PWM widths so as to provide a range of colors via dimming. The routine reads a line at a time from the main mem frame buffer into a cog mem buffer defined as RES as the last thing in the module (checked with FIT) and then cycles through the PWM routine until it's time to move on to the next line. Timing wise I'm able to squeeze in about $40 PWM periods per line before I have to move on to the next line to keep the overall refresh rate at or above 60hz to avoid flicker.
Anyway- the bizarre pasm problem: I used movs and movd instructions in order to read in the longs from main mem to the cog buffer, and then to read the cog buffer back and process it into individual PWM steps so individual LEDs would be on or off as required. I was careful to ensure there was always at least one instruction between the movs/movd and the affected instruction. When I ran the routine under pasd .7, it would work fine, but when I removed the pasd kernel and ran it normally, the first pixel of each row would be fine but all the remaining columns would display garbage. Spent hours trying to nail down the difference between running under pasd and not, with no luck- wasn't a timing or shift register bandwidth problem for sure, and I ultimately solved it by eliminating the in-cog buffer and just going straight from reading from main mem to the appropriate PWM translation. I was trying to save clocks from hub synchronization, but I think in the end it probably would've been slower anyway even if I had found the problem. But I'm still puzzled by the odd behavior where the code ran as expected in the debugger but failed in normal execution.
I know it's impossible to diagnose without posting the code, but has anyone else run into odd behavior differences between pasd and "normal" running of a pasm routine? I have to suspect my cog mem array management by movs/movd as somehow corrupting the buffer, but I couldn't find anything wrong with it. (scratches head.) Anyway, it's at least working now by eliminating the complexity.
The project is a simple LED matrix controller, although it's an 8x8 common cathode rgb matrix from Sparkfun, so it's got a bit more wiring than an ordinary single color unit. It's wired up through 32 bits worth of serial shift registers, which form a long, divided into four bytes of Row/red/green/blue. Row is a bit mask, one bit per row, and the rgb bytes are masks for those colors in their respective columns. Being a common cathode matrix, I am cycling through the rows so only one bit is set in the row byte at a time, while any arbitrary rgb colors are set in the columns for that row. Repeated shifting out of the full 32 bits, one line at a time, basically turns this into tv-style raster scanning. I imagine this is fairly conventional.
Anyway- the purpose of the pasm routine is to read a main memory frame buffer defining rgb pixels (upper byte wasted) with rgb values from 0 to $ff, defining PWM widths so as to provide a range of colors via dimming. The routine reads a line at a time from the main mem frame buffer into a cog mem buffer defined as RES as the last thing in the module (checked with FIT) and then cycles through the PWM routine until it's time to move on to the next line. Timing wise I'm able to squeeze in about $40 PWM periods per line before I have to move on to the next line to keep the overall refresh rate at or above 60hz to avoid flicker.
Anyway- the bizarre pasm problem: I used movs and movd instructions in order to read in the longs from main mem to the cog buffer, and then to read the cog buffer back and process it into individual PWM steps so individual LEDs would be on or off as required. I was careful to ensure there was always at least one instruction between the movs/movd and the affected instruction. When I ran the routine under pasd .7, it would work fine, but when I removed the pasd kernel and ran it normally, the first pixel of each row would be fine but all the remaining columns would display garbage. Spent hours trying to nail down the difference between running under pasd and not, with no luck- wasn't a timing or shift register bandwidth problem for sure, and I ultimately solved it by eliminating the in-cog buffer and just going straight from reading from main mem to the appropriate PWM translation. I was trying to save clocks from hub synchronization, but I think in the end it probably would've been slower anyway even if I had found the problem. But I'm still puzzled by the odd behavior where the code ran as expected in the debugger but failed in normal execution.
I know it's impossible to diagnose without posting the code, but has anyone else run into odd behavior differences between pasd and "normal" running of a pasm routine? I have to suspect my cog mem array management by movs/movd as somehow corrupting the buffer, but I couldn't find anything wrong with it. (scratches head.) Anyway, it's at least working now by eliminating the complexity.
Comments
You can test your routine using pPropellerSim sourceforge.net/projects/ppropellersim
Can you post the pasd-working code that fails in real world test ?