32x16cm p10 led panel
You have to know how these panels are scanned. If we were to keep things neat, and use the logical left to right, top to bottom insertion of the data into the buffer, you'd find that your data is NOT where you want it to be on the physical screen. Now, you have a crazy thing called 'DMA,' who's contantly throwing data from the buffer at the panel, in a format that the panel can understand. It's likely in a format that reads left to right, top to bottom. So you have a bunch of data that you want to display on the screen. Unfortunately, this is the case for the buffer that is sent out via DMA. Have you ever cleaned your workshop, only to find that nothing can then be found? In it's prior state, it may be messy, but you know where everything is.
#32x16cm p10 led panel full#
Moving forward, when I calculate framerate, I'll divide the actual framerate by the bit depth (8), since 8 frames represent a full frame. The above method allows us to create 8 bit (or whatever you choose) shading, using PWM and BCM, all in 8 frames of the display. So we now have Timer 1 controlling the clock and sending requests to the DMA to transfer all our data, and we have Timer 2 controlling the PWM for the OE.
#32x16cm p10 led panel update#
TIM2->CCR1 = 0 //turn off displayTIM2->EGR |= ( 1<< 0) //generate update event to force the above into the shadow register and make sure the pwm stops immediately
#32x16cm p10 led panel code#
Therefore we need to not only set the capture compare value to zero, but we also need to force an update event immediately after to prevent the PWM from finishing out its cycle as shown in the code below. This is because the capture compare value is double buffered, and the capture compare register will not update the shadow register until an update event is generated, which under normal timing settings will not happen until an overflow occurs. On the STM32 devices, running in PWM mode, simply setting the capture compare value to zero will not immediately turn off the PWM. On the 8th frame, the PWM will be a value of 128, and will represent the MSB of the byte we want to display.Ī side note on the method above: We have to make sure the PWM is completely off before toggling the latch pins in the ISR, else you'll get TONS of ghosting. On the next frame the PWM value will be 2, and will represent the 2nd LSB, and so on. When we display the first frame, this PWM value will be 1 and will represent the LSB of the byte (8-bits) we want to display. To get an 8-bit depth of shading, we will implement a PWM on the output enable pin of every panel. To overcome this, we will use a mixture of both PWM and BCM. Given the above, it would mean that for the 8th bit of shading we would need (128+64+32+16+8+4+2+1) * (1 row display time), which is unacceptable and would crush any chance of having a decent framerate. And X in this case would be the total time it takes to display 1 row, since you can't display a row faster than it takes to write data to it. The whole idea behind BCM is that you would display your LSB for X clock cycles, then display the 2nd LSB for 2*X clock cycles, next for 4*X, next for 8*x, etc. You can get a primer on it here if you are unaware of what it is. Furthermore, since we're using 4 rows of panels and they all share a common OE pin, it would mean that 8 lines on the entire display (128*8=1024pixels) would all have that 50% shading.Įnter BCM. So if one pixel should have a shading value of 128 out of 256, or 50%, then all the other pixels in both rows will have that shading value as well. Remember from my first project log that each panel displays 2 rows at a time. Simply set the output enable (OE) pin with a PWM value for each pixel when it is being displayed. This is where things get fun.Īt this point, we'd like to use PWM. At this point I have a panel that is free-running, with the exception of one ISR that executes after every row of data is shifted out.