STM32 hall + encoder timer synchronization - controls

I'm using two timers tim3 and tim4 for counting motor encoder readings (tim3) and handling hall sensor inputs (tim4. Inputs ch1, ch2 and ch3 XORed into TI1 of TIM4 running in hall interface mode). What I would like to do now is to synchronize the two timers so that when hall toggles, encoder timer is reset. However it seems that there is no way to combine encoder mode (in the SMS register) with reset mode such that the counter tim3 is reset when tim4 TRGO toggles. It seems that I can only choose one mode or the other but not combination of both.
Maybe I'm misunderstanding how the two timers can be combined for rotor position estimation? What is the best way to combine and sync hall sensor readings with encoder readings on stm32 without using an ISR to reset the counter manually? (Preferably I want to do this automatically in hardware. I have the manual solution working, but I'm not 100% happy with it).
The chip is stm32f103.

In CR2 each timer has an output signal (MMS). In SMCR each timer has input signal modes (SMS).
When you set the Hall timer to Compare Pulse and the encoder timer to Reset Mode, I think the encoder timer will reset each time input capture on CH1 of Hall timer.
If this is possible in your chip depends on the interconnects between the timers.
See TIMx Internal trigger connection (ITR).
SMS bits are already on encoder mode. You can't have both reset and encoder mode.
You can trigger a DMA operation from memory to TIMx->EGR:UG.
TIM3_CH1 can trigger a halfword memory to peripheral operation on DMA1 channel 6 with data 0x0001 to TIM4->EGR.
This will cause TIM4 to re-initialize the counter.

Related

How do i get a 100kbps clock for an I2C on Quartus Prime?

I am doing a university project in which i have to build a I2C which have only one slave and will have to transmit a data with 5 bits, 4 bits for the number which is in the range of 0 to 9 and 1 bit to read or write, i'm using a DE10-LITE with VHDL for this project, which has a 50 Mhz default clock, i was looking into the "ALTPLL" inside quartus prime but i can't find the option to set my clock to 100kbps, i did find in the in some forums that the "Set up PLL in LVDS mode" enables that, but for some reason quartus won't let me activate it. My SDA will be 100kbps, and the SCL 50mhz.
As the Other people have said: You don't need a PLL for that. If you already have a default clock of 50MHz then you just need to divide that by 500, using a counter, and then you have your 100kHz clock.
Anyways, you would want to start the counter only when there is a request on the bus. So user16145658 is correct: The generated clock should be the output of your state machine.
You don't need to change the clock of the FPGA, since you are using an FPGA, you only need to implement an i2c core to communicate with the i2c device.
And the i2c specification specifies the rate of i2c
Standard mode (Sm) 100 kbit/s
Fast mode (Fm) 400 kbit/s

GPIO32 pin works in analog mode, always reads 0 in digital mode

I'm having some difficulty getting PCNT pulse counting working with a prototype ESP32 device board.
I have a water level sensor (model D2LS-A) that signals state by the frequency of a square wave signal it sends to GPIO32 (20Hz, 50Hz, 100Hz, 200Hz, 400Hz).
Sadly, the PCNT counter stays at 0.
To troubleshoot, I tried putting GPIO32 in ADC mode (attenuation 0, 10-bit mode) to read the raw signal (sampling it many times a second), and I'm getting values that I would expect (0-1023). But trying the same thing using digital GPIO mode, it always returns 0, never 1 in all the samples.
Since the PCNT ESP IDF component depends on reading the pin digitally, the counter never increments past 0.
So the real problem I'm having is: why aren't the ADC readings (between 0-1023) translating to digital readings of 0-1 as one would expect?

Multiple PWM Channels on PIC

I use the PIC16F88 for my project, with XC8 compiler.
What I'm trying to achieve is to control 4 LEDs with 4 buttons, when you press a buttons it increases the duty cycle of the corresponding LED by 10%.
When you press the button on RB0 it increases the duty cycle of the LED on RB4, and so on.
Every LED is independent, therefore it can have a different duty cycle.
The problem is that the PIC i'm using only have one PWM module on either RB0 or RB3 (using CCPMX bit).
After some research I decided to implement software PWM to have four different channels, each channels would control one duty cycle, but most of the sources I found didn't provide any explanation on how to do it.
Or is there a way to mirror PWM to multiple pins ?
Thanks by advance for helping me out.
Mirroring is not an option.
PWM is relatively simple. You have to set PWM frequency (which you will not change) and PWM duty cycle (which you need to change in order to have 0-100% voltage range). You have to decide about resolution of PWM, voltage step that you need (built in PWM for example is 8-bit and has 0-255 steps).
Finally, you have to set timer to interrupt based on PWM frequency * PWM resolution. In Timer ISR routine you need to check resolution counts and PWM value of all your channels. Resolution count will have to reset when resolution value is reached (and start to count from 0 again, all outputs go HIGH here, also). When PWM value of output is reached you have to toggle (pull it LOW) corresponding pin (and reset it back to HIGH with every resolution count reset).
This is only one way of doing it, involves only one timer and should be most simple since your PIC is low with resources.
Hope it helps...

What is the use of transport in VHDL?

I have seen an example written in a VHDL file
Example snippet,
architecture aaa of bbb is
signal ccc : std_logic
begin
ccc <= transport global_en_lb;
....
I just want to know about transport in the above snippet.
What does it means?
Transport delays are idealised: they model propagation through a device or connection with infinite frequency response. Any input pulse, no matter how short, produces an output pulse. You could model an ideal transmission line with a transport delay, for example - any and all input changes propagate through the line. Transport delays can also be useful in testbenches for queuing up transactions on a driver.
Inertial delays approximate real-world delays. They're more complex but, in short, if you try to propagate a pulse where the pulse width is less than the propagation delay through the device or wire, then the pulse disappears. Inertial delays are the default in VHDL if you can't see a transport or inertial keyword.
At the HDL level, the actual difference between the two is in what happens when you schedule a new transaction for a signal when that signal already has scheduled transactions. For transport delays the transactions are just queued up; for inertial transactions the simulator may merge them.
On your Verilog comment: this was a bit of an after-though in Verilog (like so much else). However, a delay on the RHS of a non-blocking assignment models a transport delay:
always #(x)
y <= #10 ~x; // transport
Continuous assignments don't queue transactions, so model inertial delays:
assign #10 y = ~x; // inertial
In VHDL "transport" keyword is used to model delays for simulations.
The transport delay model just delays the change in the output by the time specified in the after clause.
The transport delay, which is used to model the delay introduced by wiring. With transport delay any pulse of small width is propagated to the output. The transport delay is especially useful for modeling delay line drivers, wire delays on PC board, and on path delays on ASIC.
To understand in terms how exactly it behaves with simulation refer link

IR emitter and PWM output

I have been using FRDM_KL46Z development board to do some IR communication experiment. Right now, I got two PWM outputs with same setting (50% duty cycle, 38 kHz) had different voltage levels. When both were idle, one was 1.56V, but another was 3.30V. When the outputs were used to power the same IR emitter, the voltages were changed to 1.13V and 2.29V.
And why couldn't I use one PWM output to power two IR emitters at the same time? When I tried to do this, it seemed that the frequency was changed, so two IR receivers could not work.
I am not an expert in freescale, but how are you controlling your pwm? I'm guessing each pwm comes from a separate timer, maybe they are set up differently. Like one is in 16 bit mode (the 3.3V) and the other in 32 (1.56v) in that case even if they have the same limit in the counter ((2^17 - 1) / 2) would be 50% duty cycle of a 16 bit timer. But in a 32 bit, that same value would only be 25% duty so, one output would be ~1/2 the voltage of the other. SO I suggest checking the timer setup.
The reason the voltage changed is because the IR emmiters were loading the circuit. In an ideal situation this wouldn't happen, but if a source is giving too much current the voltage usually drops a bit.

Resources