1 2 Previous Next 17 Replies Latest reply on Jul 5, 2017 9:59 AM by AndyMarder

    External interrupt handling

    AndyMarder

      I have a custom board with an accelerometer that generates interrupts when movement is detected.

         

      The part INT pin  is configured for open drain and active low.

         

      I have an ISR component and the input pin configured in the project. 

         

      The pin is connected to the correct port in the Pins window, according ty my schematics.

         

      I do call ISR_StartEx and pass it my ISR handler.

         

      The ISR gets called multiple times on startup ( even without any movement ) but after several seconds it stops and never gets called again

         

      Verified with the part support that it is correctly configured to generate interrupts So it must be something on the PRoC side in the setup of the ISR component or the pin.

         

      Attached is the screenshot of the pin configuration.

         

      Your help is much appreciated.

         

      Thank you

        • 1. Re: External interrupt handling
          user_1377889

          Andy, can you please post your complete project or a shortened version that shows the error so that we all can have a look at all of your settings. To do so, use
          Creator->File->Create Workspace Bundle (minimal)
          and attach the resulting file.

             

           

             

          Bob

          • 2. Re: External interrupt handling
            e.pratt_1639216

            Depending on how you configure your interrupt pin: If you set it to Level- interrupt, that would explain why it fires for a time, but then stops after a while? Otherwise, if you correctly configured the pin to interrupt on a falling-edge and the accelerometer does a pulse by pulling the output Low for a clock pulse, then I would expect it to work fine.

               

            Another thing to check is that you are clearing the interrupt for the pin when handling the ISR (I don't remember if the ISR routine does it automatically or not); If it isn't cleared, then that would cause back-to-back interrupts as you are seeing.

            • 3. Re: External interrupt handling
              AndyMarder

              Attached is the project that sets up and handles the interrupt for the accelerometer . I've been playing with pin configuration and in the current one I do get the orientation interrupt correctly i.e only when the device orientation changes. However the  data ready (i.e movement detected) interrupt fires constantly 

                 

              This could be the part issue , but I want to make sure that the  pin is configured  correctly. I do call clear interrupt routine in the ISR ( function Acc_ISR() in mma865x.c)

                 

              Thank you for all your help!

              • 4. Re: External interrupt handling
                AndyMarder

                Update on the interrupt issue

                   

                Interrupts in the project in the previous post work as designed. The orientation interrupt fires only when device's orientation changes. The "data ready" interrupt fires constantly because the part samples constantly and just signals that it has data. So that's all as designed.

                   

                However there is still a problem. When I added a  BLE handler routine and call CyBle_GappStartAdvertisement() on CYBLE_EVT_STACK_ON, the accelerometer interrupt gets messed up

                   

                With CyBle_GappStartAdvertisement function commented out this is what I see ( and this is what I expect ) 

                   

                -Stop at a breakpoint  in the ISR (Acc_ISR() in mma865x.c)

                   

                -Stop at a  breakpoint where the data is being read. (ReadMovementData() in mma865x.c) When the device moves the data changes. This happens at 1 second interval as the part reads the data and raises the interrupt

                   

                -Stop at a breakpoint where the orientation change is handled. (line 265 in mma865x,c)  Happens only when device orientation changes

                   

                When CyBle_GappStartAdvertisement() is called on CYBLE_EVT_STACK_ON:

                   

                Execution never stops at more than one breakpoint 

                   

                The data never changes even though the part is moved

                   

                I tried to play with the order of initialization i.e initialize the part after the CYBLE_EVT_STACK_ON event - that did not help

                   

                Any suggestions what the problem is and how to fix it?

                   

                Thank you

                   

                Andy

                • 5. Re: External interrupt handling
                  e.pratt_1639216

                  Fyi: When you set a breakpoint, the peripherals (Accel, I2C, BLE) don't stop running while the CPU is halted, and thus the interrupts can be messed up by breaking while debugging if you are not aware of what peripherals are running/doing.

                     

                  Looking at the code, it seems as if the Accelerometer interrupts are handled be the generated code to buffer data, which you then poll and read in main-loop. I would suggest messing with the interrupt priorities and see if setting the accelerometer to higher priority (lower number than the BLESS interrupt) to see if it is just unable to fire the interrupt. If you can verify that it is working without breakpoints, that would be the best as the breakpoints will cause all of the interrupt flags to be set while the CPU is halted in realtime.

                     

                  One workaround is to set the CyEnterCriticalSection() and CyExitCriticalSection() before and after the location you want to break on; It won't prevent peripheral operation iirc, but it will at least prevent flags changing/interrupting while the CPU is halted between those routines, allowing you to get by with debug points easier.

                  • 6. Re: External interrupt handling
                    AndyMarder

                    Changing interrupt priority did not help, Verified that the data does not get updated. I have a service that I can connect to and dump real time  accelerometer data. When I do that the data is the same even though I'm moving the part. If I poll instead of using interrupts, the data gets updated just fine.So I'm stuck :(

                       

                    PS. Is my pin configuration OK?

                       

                    PS2 

                       

                    Given the fact that the data ready interrupt fires every second anyway, maybe I should just read the data on a 1 second timer.. just thinking out loud..

                    • 7. Re: External interrupt handling
                      e.pratt_1639216

                      Fyi: There is a method to updating the advertisement data. See this thread for details/link to example project(s): http://www.cypress.com/forum/psoc-4-ble/updating-advertising-packet-real-time-data

                         

                      Keep in mind that variables accessed from interrupt routines need to be declared as volatile, otherwise they will cause issues.

                         

                      When you say service you connect to, do you mean a BLE service?

                         

                      PS: Your pin configuration looks fine assuming the hardware matches ;)

                         

                      PS2: If you know the data rate/sampling you want, then doing it with polling will probably work just as well as trying to debug/implement interrupts. Interrupts are inherently "multithreaded" in nature, and thus can cause alot of issues :(

                      • 8. Re: External interrupt handling
                        AndyMarder

                        Thank you I'm aware of that, portions of my code are based on the Dynamic Broadcaster project.

                           

                        The service is a BLE service ,yes. 

                           

                        Good point about the volatile variable.Unfortunately that did not help :(

                        • 9. Re: External interrupt handling
                          e.pratt_1639216

                          For the interrupt mechanism, are you setting the StartEx(Acc_ISR) to register a callback for handling the accelerometer interrupts? I don't see it in the code, but I figured the generated code for the component was handling it. If not, that could be why?

                             

                          If you can, try to get it working with just the accelerometer interrupting and putting data into a buffer/variables; That way, once you are sure the interrupts for the accelerometer are working properly, you can start transferring the data to the BLE database to send to the remote device.

                          • 10. Re: External interrupt handling
                            AndyMarder

                            Yes, it's at the very end of MMA865_Init() function

                               

                            The sample I gave you does not include all the code  because some of it is proprietary , so I cannot just post on the open forum. In the complete project the data collected by the sensor is copied into the advertising packet. When I examine the packet in CySmart ( and other tools I'm using ) the accelerometer data does not change when the device moves. If I use the polling mechanism it does.

                               

                            If you're a Cypress employee, I'd be glad to send you the whole project - just let me know how I can do it privately.

                               

                            Thank you

                               

                            Andy

                            • 11. Re: External interrupt handling
                              AndyMarder

                              Another independent verification that the interrupt stops firing.

                                 

                              Added a global volatile uint64 asr_count variable that is incremented every time the ISR is called. Let the device run for 10 minutes and then put a breakpoint in the main loop to examine the value of the asr_count.. Since the interrupt fires every second I was expecting to see the asr_count to be around 600 but it is stuck at 10.  So the interrupt fires for the first 10 seconds and then stops. Ideas? 

                              • 12. Re: External interrupt handling
                                e.pratt_1639216

                                @Andy I'm not a cypress employee ;P

                                   

                                But, I don't need to see the code. I can work with general-design to help you at least be able to find it on your own :)

                                   

                                For updating the data that cysmart sees, keep in mind that you have to write to the GATT-DB on the BLESS system using the API call to set new data for the BLE connection to request from the cysmart dongle. Since it works for "polling", I'll assume you have that figured out :)

                                   

                                Under the mma865x.c, function Acc_ISR(), I'm confused by the ret value that you set/modify, but then fail to use in any way? The compiler might be optimizing away the ret = Acc_Isw_ClearInterrupt(); line. Maybe just replace it with Acc_Isw_ClearInterrupt(); instead?

                                   

                                At this point though, I don't see any red flags that stand out for what is going wrong. Maybe try adding a breakpoint for when the interrupt hits a count of 11 or 10 to see what happens on the "last interrupt"?

                                   

                                If the code is working at the beginning, then it must be failing later due to: A counter, a timer, or some sort of timing issue.

                                • 13. Re: External interrupt handling
                                  AndyMarder

                                  The variable assignment in Acc_ISR is a leftover from my experiments, the value is not used.

                                     

                                  The number of times the interrupt fires is random. 11 is just one of the values. I saw 10, 20 etc. So it is some sort of a timing issue between the BLE and my part. At this point I decided to move on and use a watchdog timer instead. Since the part  raises the interrupt every 650 ms anyway,  a WDT is a suitable workaround. I may lose a reading or two from the part, but that's not crucial to my application

                                     

                                  Thank you I really appreciate your help

                                     

                                  Andy

                                  • 14. Re: External interrupt handling
                                    e.pratt_1639216

                                    Hmm, yeah that sounds like a timing issue :(

                                       

                                    (The worst kind of bug lol)

                                       

                                    Well, WDT is indeed a good workaround for that. Too bad we can't figure out the issue. Generally, when I run into timing issues, I re-examine the ISR routines to see if they are too bloated, double check timing routines/procedures, and then if all of that fails, I implement a debug routine to see if I can get it to fire consistently by triggering bits/bytes. But, it's whatever now.

                                       

                                    Glad you have a solution to it! Good luck,

                                       

                                    Pratt

                                    1 2 Previous Next