I need to start a timer and make it fire from inside another timer interrupt, basically I need another timer to fire even when the other timer calls has not finished.
Seems that HardwareTimer disable interrupts when it fires because inside timer 2 I start timer 3 but it doesn’t fire until immediate the call to the timer 2 has finished.
The sample below is way oversimplified, but my case is that I need to start timer A when it fires I need to start timer B however timer B may need to fire before the call to A has finished.
Long story short I need to control the brightness of my RGBMatrix, and to do that I need to control the matrix OE (OutputEnable) leg time, however I cannot start this timer until the latch from the last frame has been made, Timer A triggers the latch to make it visible on the matrixx and then proceeds to build the next frame, meanwhile Timer B has to start after the latch and has to be called(fired) to disable OE at an specific time to disable the matrix output.
Hopefully I made myself clear, but the question is very simple, I need to enable interruptions re-entrancy which seems HardwareTimer disables when the interruption fires.
I tried to put interrupts() as first line inside void ISRUpdate but nothing change, ISRUpdate1 is called as soon ISRUpdate finish;
HardwareTimer timerDisplay(2);
HardwareTimer timerDisplayEnabled(3);
timerDisplay.setMode(0, TIMER_OUTPUT_COMPARE);
timerDisplay.setPeriod(100 * microseconds_per_millisecond);
timerDisplay.attachInterrupt(0, ISRUpdate);
timerDisplay.resume();
timerDisplayEnabled.setMode(0, TIMER_OUTPUT_COMPARE);
timerDisplayEnabled.setPeriod(5);
timerDisplayEnabled.attachInterrupt(0, ISRUpdate1);
timerDisplayEnabled.pause();
bool myValue = false;
void ISRUpdate(void)
{
timerDisplay.pause();
…
…
…
timerDisplayEnabled.setPeriod(brightness); // about 100
timerDisplayEnabled.resume();
…
…
// Code in here runs for 500 microseconds, 5x more than the time in the line above
…
…
timerDisplay.setPeriod(XX);
timerDisplay.resume();
// value of myValue still is false, interrupt for timerDisplayEnabled doesn’t trigger until ISRUpdate which was called from the timer 2
// unwind from the stack.
}
void ISRUpdate1(void)
{
timerDisplayEnabled.pause();
myValue = true;
}
hard to tell what you meant by “fire”.
CMx chips allow priority / subpriority over its interrupts so take a look at the datasheet to see how that can be set-up – the ISRs are re-entrant.
another feature is interrupt-chaining (potentially what you are trying to do), whereby a pending ISR can be executed without the exiting the current ISR, reducing ISR latency.
With that said, generally you don’t need something this fancy so your “problem” potentially has a solution vastly different from your current approach.
Is not fully re entrant what I want to do as you mention really is interrupt-chaining, since I want Timer B to be called even when Timer A has not finished.
I wish there was a simpler solution but predictable I need to disable the OE at a particular time (just set the output to high), Timer A is executing a bunch of high perf code to build the next frame, so it can’t stop to check if the elapse time to disable the OE is done, basically the check would have to be done at every line and consume more CPU than the code to build the next frame. Also Timer B for the OE has to be started only once the matrix data has been latched, so the Timer B has to start from Timer A interrupt.
Setting the priorities did the job.
nvic_irq_set_priority(NVIC_TIMER2, 15);
nvic_irq_set_priority(NVIC_TIMER3, 0);
the first question should be if the OE pin can be enabled in the middle of a frame transmission. if yes, you can simply drive it with a pwm pin. 0-100% duty cycle.
if the OE pin can only be enabled at the end of a frame transmission, your ISR flow should be like this:
timerA isr:
[optional]disable the OE pin;
transmit the frame; //assuming it is short
enable the OE pin;
enable timerB; //can be done with 1 instruction
exit;
When brightness is at 15 latency is not an issue since, the OE enabled times are 16µs, 32µs, 64µs, 128µs for the 4 bits however definitely latency is an issue when the brightness is at 0 since for the 4 bits I need to enable bit 0 for 1µs, bit 1 for 2µs, bit 2 for 4µs and bit 3 for 8µs, the timerB handler for the bit 0 lags about 700ns so ends up with a pulse of 1.7µs instead 1µs. then when brightness is at 0 colors tones 1, 3, 5, 7, 9, 11, 13, 15 won’t render perfectly but can’t really be noticed.
I thought about driving the OE with PWM however I was afraid (theory) that the display will display artifacts if when OE is enabled/disabled during latching and was looking for something more predictable.
However for testing I’ll try to drive OE with PWM only after latch completed and before the previous frame starts, if that works I don’t need timerB
RGB animated matrix
viewtopic.php?f=19&t=3104
.
so if you are refreshing your display at 100Hz (way higher than necessary), the minimum on cycle you need to hit is 0.1% * 10ms = 10us. On a 72Mhz mcu, that translates into 720 ticks. shouldn’t be a problem.
if it is, there are other ways to address the minimum dc issue.
In the case of the RGB matrix and BCM I need to run at least at 200hz refresh rate or artifacts start to present, this is better described here
http://www.batsocks.co.uk/readme/art_bcm_1.htm
The time slice for bit 0 is just 15μs, if I run continuous PWM on OE without care of sync with latch then I would need at least 10 pulses of PWM for every bit to avoid artifacts which would translate on a 1μs period or 1Mhz PWM.
How do I change the default PWM frequency of 1Khz? On Arduino seems to be with setPwmFrequency() however seems this function is not available on STM32.
Another way would be to sync enabling the PWM on the beginning of every bit when the bit latch then I would need fewer PWM pulses since duty cycles will be fair for all bits however the default 1Khz is not even close for that either.
In the image you can see
D: is a whole frame (250Hz)
OE: running PWM at 1Khz (which a single period is taking what it takes 4 pixels to render)
Latch: Is when the data of every bit is send to the matrix, there is a zoom for bit 0 that takes 15μs, if I want PWM to work I need to fit at least 10 PWM OE pulses in there or fewer pulses if I can synchronize with the latch going low.
By the way I’m running the blue pill overclocked at 128Mhz.
IMO, this is equivalent to a “normal” PWM with constant duty cycle, wherein you have to keep the total low/high pulse ratio within a BCM period.
What also important, I think, it is the highest allowable OFF cycle to avoid flickering, which would be ~= the total period of a BCD train.
When you talk about 200Kz, what exactly is this referring to? To the period of one pulse or the total period of a BCM train?
The F103 timer PWM is very powerful, capable to set up in very different ways. You could also do some sync with other pulses when needed.
Do you have a plot showing how exactly your signals should look like? If possible with periods on it?
I need to run the PWM at least 1000 times faster.
It is certainly possible to run the pwm module at 1Mhz.
But when your requirement becomes that extreme for such a simple task, you may want to re-examine your approach, both software and hardware.
Case in point. Ppm is often used as a software implementation of pwm, when the hardware isn’t available. It is not intuitive to implement ppm through a pwm hardware module.
I don’t remember all the details, the datasheet shows what it can do, but perhaps that can remove the need to have 2 ISRs completely and leave only 1.
I think that one of the modes is to enable the second timer to count once the first time reach a certain count, which I understand is more or less what you are trying to do with the 2 timers and the ISR.
Still didn’t get any hint how to change the PWM frequency. Do you know how?
Current approach with two timers works fine, and blue pill only take care of rendering so the current approach is good enough, however when brightness is at minimum the isr introduce a 700ns latency which isn’t big deal.
However I keep looking for alternatives, if I can drive PWM at 1Mhz I may not need the secobd timer however from what I read PWM uses a timer as well, so is not that I’m saving a lot other than some code.
Anyway… anything is on the table to change,
How do I change the pwm frecuency?
Thanks!!
viewtopic.php?f=19&t=3037#p39304
viewtopic.php?f=19&t=3037&start=10#p39347
Thanks!!!!!
By the way now I know where the pink pins info is used in the image ![]()
However still I don’t have clear for example, PWM on PB0 is controlled by T3C4 (Timer3 Channel 4) but what means T1C3N next to it???
After playing the video several times during second 3 and 4 I see some artifacts that can’t be seeing with the naked eye but on the video looks like some pixel ghosting, I did not have that before, I wonder if the PWM frequency is the problem since is not synchronized with the latching, I’ll see if increment the PWM to 1.28Mhz have the same issue.
I would bet anything that is because the PWM is not synchronized with the latch so the OE is going low and enable the display while the data is still feed into the shift register.
Well… going back to the drawing board ![]()
My guts tells me if I synchronize the OE PWM start/stop with the latch this problem will go away, also synchronizing will make the number of pulses constants when the display is visible so I suspect that just lowering to 200Khz (about 4 pulses for bit 0) will be more than enough since now the duty cycle will be the fair and same for every bit, it would require some extra lines of code as it did with the 2 ISR timer chained events, however I think it will work.
having the master to trigger to slave; or running the slave in single pulse mode….
what means T1C3N next to it???
negative.
Steve wrote,
“Well, I cannot see why you would anyway need BCM, that’s just PWM with repeatedly variable duty cycle.”
From what I researched with BCM I need way fewer instructions to display a frame with 128×32 at 16 tones achieving much higher refresh rate of at least 250Hz.
Currently the main loop to display a frame is basically; cycle for the instructions I put below with barely any extra processing.
Based my work from the explanation http://www.batsocks.co.uk/readme/art_bcm_1.htm however the implementation was initially the Adafruit RGB matrix driver implementation that I heavily end up modifying..
Instructions to create a frame:
(1 x reset PWM OE) + (1 x set latch) + (1 x Row Address = “2 rows per instruction”) + (128 x clock set) (1 x R1G1B1&R2B2G2 data “6 colors set per instruction”) + (128 x clock reset) + (1 x set PWM OE)) x 4 bits x 16 rows = 16704 instructions per frame
so with 16704 instructions I can display a whole RGB frame on the matrix, may be possible but honestly down know how to make it happen with PWM instead BCM.
implementing ppm over pwm hardware just makes zero sense.
Most usual is 1/16. Means it has 4 lines A,B,,C,D to control the row 1-16- & 17-32, so if the address is 0b0001 then data will be sent to row 1 AND 17, however has two data lines per color R1, R2, G1, G2, B1, B2 so after every latch every change in address plus the 6 data lines to control colors in two rows at the same time, there are other matrix that are 1/32 Means that address lines are A,B,C,D,E and just R,B,G, however 1/32 are great to control matrix of 64 rows since usually have an extra address line A, B,C,D, E and R1, R2, G1, G2, B1,
beyond the address and data bus there are 3 more lines, latch, clock outputenable
Start to set the address/data while sending the train of clock pulses (128 for 128 columns), then latching sends the data to the LEDs.
Output enable is just a switch to “turnon/turnoff” the whole display.
To making it very simple, how would you implement a PWM control with 1 row, 8 columns, 16 tones, monochromatic at 250Hz refresh rate with 3 wires? After that is just a question of scale.
Basically you have 3 wires to control 8 LEDs in a row
R – Data line
L – Latch
C – Clock
if I were to write a driver for this, I would establish a buffer: it contains information about the display’s construction (including current frame index, or brightness) and frames. If you write a slave receiver here (spi or uart), you can turn the controller-less display into a common / universal display and commercialize it potentially. In that set-up, the master can simply communicate to the display unit with command data + images and the slave will handle the rest.
each frame then contains a current index for the line being scanned.
a display routine is periodically called from the isr. The display routine would perform something like this:
1) fill the shift registers with line data;
2) turn on the current mux line; this assumes that the mux lines cannot be turned off.
3) strobe out the shift register data;
4) advance the line index to the next line;
the logic is slightly different if you use DMA under-run interrupt in step 1) above.
Your OE line is driven separately via a pwm module – using the OE pin to a PWM a HC595 has been done for ages.
You can take a look at this basic logic at work here (https://dannyelectronics.wordpress.com/ … ment-leds/) and here (https://dannyelectronics.wordpress.com/ … ment-leds/) and here (https://wordpress.com/post/dannyelectro … s.com/4113).
The actual implementation will be different, the hardware involved will be different but the basic logic is the same.
If you look at my previous posts with Steve about slave DMA SPI this is exactly what the blue pill job does, it is a RGB Matrix rendering driver ![]()
The blue pill only function for me is use the SPI bus to take an input of ARGB (1555) frames and display them on the matrix, internally is using a DMA buffer for SPI and double buffer for the Matrix data to avoid tearing of the screen, doing this way I have the whole ESP8266 CPU to create frames with my graphic library as the Clock, Animations, blending, effects, OSD (on screen display) with alpha support, etc and then send the frame as is to the blue pill where it take care of encoding the ARGB (1555) frame into whatever the matrix understands, in this case RGB (444)
In fact I can disconnect the ESP8266 from the STM and the last frame will keep rendering on the matrix, also the SPI bus is full-duplex where I can send instructions from the ESP as get/set rtc, set the brightness of the display from the ESP8266 or control other things like the buzzer (STM also has coded a tone synthesizer that is driven over the same SPI bus), the STM DMA bus also is driven with an interruption over the CS so the DMA buffer self-heal when receives corrupted data, also has other cool features as partitions of frames since sending a full frame from the ESP would take some time and the STM will take some time to decode a full frame as well, this synchronization would slow down the two CPUs, instead the ESP8266 sends 1/8 of a frame at the time arbitrarily so the SPI burst transition from ESP to STM is very short and give time to the STM to decode 1/8 of a frame while is receiving another 1/8 frame in the DMA buffer in parallel.
This behaviors allow as very high speed animation to automatically omit sending some portion of the frame since a new 1/8 of frame is coming behind, means the animation will never be slow down because of the CPU processing, collateral effect will be that just some frames may be skipped, that’s all
Your 4 points seems a generalization how to do it however doesn’t share any hint or mechanic how pwm is used to give different tones for every pixel, still reading what you mean, also I’ll go over all the links, however if I can understand well the following, then I can scale it as well,
PWM with 3 wires to control 8 LEDs in a row
R – Data line
L – Latch
C – Clock
With BCM I need only 4 very short clock pulses plus 4 latches to display a pixel with 16 tones. In the case of 128 columns just 128×4 clocks plus 4 latches. how many clock cycles and latch do you need to display a pixel with 16 tones with PWM?
The research lead me to BCM, I know my own PWM implementation sucks, and I’m interested to know what you have in mind at this scale. Remember that the matrix is 128×32 and has 6 shift registers R1, R2, G1, G2, B1, B2 and want to have high refresh rate, so the PWM algorithm needs to be very efficient, most than everything I’m interested to learn an efficient PWM technique.
If I would use my own and old PWM algorithm I would need 128 clocks * 16 latches, that would be almost 4 times greater than BCM and basically probably I could get only 60Hz instead 250Hz.
The original idea in the images below was to chain 74hc595d controllers vertically and horizontally to control a larger Matrix 128×32 and replacing only the MCU, so naive myself that I thought with 16Mhz was enough to do all that.
couple by etch resist pen hand drawn ?
and the ones with very, very clean isolation cuts ?
stephen
that’s probably the disconnect. Take a look at hc595’s datasheet and see how the OE pin works with respect to the rest of the circuitry.
for large matrix, that’s a pin efficient but not time efficient implementation: as the row data is serial as well.
a better approach is to use a mux (or multiples of them).
Started with electronics again as a hobby about 5 months ago after 20 years of doing nothing with electronics so I was trying to find a quick method to iterate and create prototypes.
1) The board in the center was made with paper toner transfer and etching with ferric chloride, I tried about 10 different methods, I never could master the process, even bought new printers, papers, chemicals and so on, big failure so far, always for one reason or another some toner is not transferred and had to hand touch with a pen, as you can see in the image I sent before. Currently the boards I do with toner transfer are not all bad however I cannot go below 80mil traces, unusable unless is a very basic PCB.
2) The PCBs on the side are made with a CNC machine, these were made about 30 days after trying many techniques with the machine, at first they were a mess and started to improve the technique, probably I did about 100 PCBs until vastly improved the technique, these boards are old, at this moment after 5 months I “mastered” the process and I do my double side PCBs with a 15mil traces and they look 10 times better than the picture above.
3) Started to play with Pre-sensitized PCBs, transparencies and UV light, however Pre-sensitized PCBs are way too expensive, so dropped this technique in favor of the CNC machine, however Pre-sensitized PCBs can gain quite a bit of time for complex PCBs since the CNC machine can be working for 1hr or more for every side.
These are some of the keys in the technique I’m using.
a – Use good carving bit with a .1mm tip
b – Center the carving bit with a strobe light
c – Make a thing layer of WD40 while the machine is carbing
d – Pre-level the work surface
e – Secure the PCB to the machine very flat using double side tape.
f – Autolevel algorithm to measure imperfections of the PCB and readjust bit height in the source file
At this moment my CNC machine carves only 0.05mm from the copper, so the carving bit barely touch the fiber glass.
I’ll see if I find new PCBs to show how they looks like, they are really good at this time.
This is the machine I got:
https://www.ebay.com/itm/USB-3Axis-CNC- … 25e8de4d39
I had to make some modifications to the machine to add an autolevel input since by default these machine do not have them.

