I'm currently reading values from a PS/2 mouse, which is working perfectly! - I'm trying only to read from the mouse, when the mouse sends a clock signal (falling edge), so i'm trying to use a interrupt. This is some of my code so far:
Interrupt handler:
extern struct mouse mouseData;
CY_ISR(PS2_interrupt) {
ISR_getMouseData(&mouseData);
}
This interrupt is giving me the follwing result, which is perfect:
I'm moving the mouse to the right, and it's outputting the right thing, i can't however do anything in the main for loop. If i for instance print something on the display in the main loop, nothing happends, but it can still read data from the mouse, whenever the mouse is sending..
I found out that you should clear the interrupt using this function:
isr_PS2_clock_ClearPending()
When i write this function in the interrupt handler i'll get this:
This is the same movement at before, but as you can see, the data i corrupted. I can however execute things in the main loop, whenever the intterrupt is not called.
What am i doing wrong in terms of handling the interrupts?
Try to use isr_PS2_clock_ClearInterrupt() to clear the Flag
Related
Im working on a STM32F411CEU6 using STM32CubeIDE, Im making a library that works whit UART interruption, inside the UART interruption Im using the HAL_GetTick function to keep track of time, when I use this function outside the interruption It work properly, but when I try to use it inside the interruption the uwTick halt.
I understand that uwTick is a global variable that is incremented on interruption, my first guess was that the UART interruption had greater priority over the System tick timer interruption (I'm guessing that this interruption is the one that trigger the uwTick increment), but the System tick timer interruption has a higher interruption in the pinout configuration UI.
What is going on?
Should I change my approach and use a timer (reading the counter inside)?
additional information:
-Im triggering the interruption whit the HAL_UART_Receive_IT(&huartx, &USART_receive[0], 1), where USART_receive is a receive buffer
-The function that use the HAL_GetTick function is being call in the void USART1_IRQHandler(void) handler after the HAL_UART_IRQHandler(&huart1) function
Thanks in advance!
A higher interrupt priority is represented by a lower number and vice-versa. Maybe you need to switch the priorities around to do what you want.
However, please note:
It is conventional for systick to be one of the lowest priority interrupts in the system, with only pendsv/svcall lower.
It is generally considered a bad idea to try to delay within an interrupt, especially for several milliseconds. It is probably better to set a flag or something in the interrupt and let your main context carry out the delayed action.
So im using gtkmm specifically here.
What I'm working on:
I'm implementing a feature in which when I press in a certain window a parameter is increased/decreased depending on if the mouse moves left/right.
What needs to be done:
To be able to somehow loop in the button press callback method -(doing so as each iteration would store the new value of the cursor position and compare it to the inital position to determine wheter increase value or decrease)- until the button is released.However the event which is sent remains the same so I cant just for example check to see if the events type becomes GTK_BUTTON_RELEASE. I have also tried to use a flag which is set to false in the button release call back, however the release callback isnt even called as the execution is stuck in the now infinite loop.
Thoughts
Im thinking maybe the solution could be a certain something to do with signals.
Update:
Gtk has two functions for doing what I was saying here exactly which are , gtk_events_pending(), and gtk_main_iteration(). Hever turns out having a limitless loop inside an event is considered a bad practise and its better to use other methods like here for example using GdkEventMotion, or other types.
I have a strange problem. When pyglet app starts it just draws 1-2 frames then freezes. on_draw event just stops occuring. But everytime I move mouse or press keys, on_draw event dispatches as well. In short I have to move mouse to make my pyglet application basically work.
This is actually happens in Windows. In Ubuntu with compiz I've to move mouse just once then application starts working normally.
This is my code example:
#!/usr/bin/env python
import pyglet
win = pyglet.window.Window(width=800, height=600)
label = pyglet.text.Label('Abc', x=5, y=5)
#win.event
def on_draw():
win.clear()
label.x += 1
label.draw()
pyglet.app.run()
Here's a video explaining things.
I came across this last night while trying to figure out the same problem. I figured out what causes this.
I had used a decorator and put my updates in the on_draw method, and it would run okay for a little while, then it would freeze, only to start working again when I moved the mouse or hit the keyboard. I tried all sorts of tricks to figure it out, I finally thought that maybe things were just running too fast, and that putting them in a batch and letting pyglet decide when to update them would be better. It worked.
I also scheduled things so that they would run about twice as fast as my refresh rate, but not so fast it would bog anything down. This is more than enough for smooth animations.
needles_list = [gauges.speedometer.Needle(speedometer_data, needle, batch=batch, group=needles),
gauges.tachometer.Needle(tachometer_data, needle, batch=batch, group=needles)]
def update(dt):
for needle in needles_list:
needle.update(dt)
pyglet.clock.schedule_interval(update, 1/120.0)
gauges.speedometer.Needle and gauges.tachometer.Needle are subclasses of pyglet.sprite.Sprite, and I wrote an update method for each of them. I then called their draw method in on_draw as normal.
#window.event()
def on_draw():
window.clear()
batch.draw()
I know this question has been up for a while, and the asker may have given up already, but hopefully it will help anyone else that's having this problem.
I had a similar problem of update events not getting called (using pyglet from Cygwin on Windows), and it turned out there was a bug:
https://groups.google.com/forum/#!msg/pyglet-users/Qp1HzPHcUEQ/A9AFddycLSAJ
I'm not certain it's the same problem you're having, but it seemed worth mentioning. I ended up hacking the file mentioned (pyglet/app/win32.py) by hand (setting self._polling = True around line 105, in Win32EventLoop._timer_func) and all my updates started flowing just fine.
What is the best way to handle this situation on an iPhone device: My program ramps the pitch of a sound between two values. A button pressed calls a method that has a while loop that does the ramping in small increments. It will take some time to finish. In the meantime the user has pressed another button calling the same method. Now I want the loop in the first call to stop and the second to start from the current state. Here is the something like what the method should look like:
-(void)changePitchSample: (float) newPitch{
float oldPitch=channel.pitch;
if (oldPitch>newPitch) {
while (channel.pitch>newPitch) {
channel.pitch = channel.pitch-0.001;
}
}
else if (oldPitch<newPitch) {
while (channel.pitch<newPitch) {
channel.pitch = channel.pitch+0.001;
}
}
}
Now how to best handle the situation where the method is called again? Do I need some kind of mulitthreading? I do not need two processes going at the same time, so it seems there must be some easier solution that I cannot find (being new to this language).
Any help greatly appreciated!
You cannot do this like that. While your loop is running no events will be processed. So if the user pushes the button again nothing will happen before your loop is finished. Also like this you can’t control the speed of your ramp. I’d suggest using a NSTimer. In your changePitchSample: method you store the new pitch somewhere (don’t overwrite the old one) and start a timer that fires once. When the timer fires you increment your pitch and if it is less than the new pitch you restart the timer.
Have a look at NSOperation and the Concurrency Programming Guide. You can first start you operation the increase the pitch and also store the operation object. On the second call you can call [operation cancel] to stop the last operation. Start a second operation to i.e. decrease the pitch and also store the new object.
Btw: What you are doing right now is very bad since you "block the main thread". Calculations that take some time should not be directly executed. You should probably also have a look at NSTimer to make your code independent of the processor speed.
Don't use a while loop; it blocks everything else. Use a timer and a state machine. The timer can call the state machine at the rate at which you want things to change. The state machine can look at the last ramp value and the time of the last button hit (or even an array of UI event times) and decide whether and how much to ramp the volume during the next time step (logic is often just a pile of if and select/case statements if the control algorithm isn't amenable to a nice table). Then the state machine can call the object or routine that handles the actual sound level.
I wrote an an idle hook shown here
void vApplicationIdleHook( void )
{
asm("nop");
P1OUT &= ~0x01;//go to sleep lights off!
LPM3;// LPM Mode - remove to make debug a little easier...
asm("nop");
}
That should cause the LED to turn off, and MSP430 to go to sleep when there is nothing to do. I turn the LED on during some tasks.
I also made sure to modify the sleep mode bit in the SR upon exit of any interrupt that could possibly wake the MCU (with the exception of the scheduler tick isr in portext.s43. The macro in iar is
__bic_SR_register_on_exit(LPM3_bits); // Exit Interrupt as active CPU
However, it seems as though putting the MCU to sleep causes some irregular behavior. The led stays on always, although when i scope it, it will turn off for a couple instructions cycles when ever i wake the mcu via one of the interrupts (UART), and then turn back on.
If I comment out the LPM3 instruction, things go as planned. The led stays off for most of the time and only comes on when a task is running.
I am using a MSP4f305438
Any ideas?
Perhaps the problem is the call __bic_SR_register_on_exit(LPM3_bits). This macro changes the LPM bits in the stacked SR, so it must know where to find the saved SR on the stack. I believe that __bic_SR_register_on_exit() is designed for the standard interrupt stack frame generated by the compiler when you use the __interrupt directive. However, a preemptive RTOS, like FreeRTOS, uses its own stack frame typically bigger than the stack frame generated by the compiler, because an RTOS must store the complete context. In this case __bic_SR_register_on_exit() called from an ISR might not find the SR on the stack. Worse, it probably corrupts some other saved register value on the stack.
For a preemptive kernel I would not call __bic_SR_register_on_exit() from the ISRs. The consequence is that the idle callback is called only once and never again, because every time the RTOS performs a context switch back to the idle task the side effect is restoring the SR with the LPM bits turned on. This causes a sleep mode (which is what you want), but your LED won't get toggled.
Miro Samek
state-machine.com