Discussion:
using nuttx to decode EXTI signals
(too old to reply)
f***@public.gmane.org
2014-03-20 16:33:53 UTC
Permalink
Hello,

I am working on a PPM decoder, part of a NuttX based project. I plan on using a specifically configured EXTI pin in order to capture PPM edges. In my vision, it would be best to use the external interrupt handler to write down the times, at which the edges were captured, form a "interval log" once the expected amount of pulses was captured, send this "interval log" to a specific PPM-decoding thread, and post a semaphore for this thread to decode it.

I have a few questions, concerning this algorithm:


1. How do I exchange data between this interrupt-handler level and my thread, running the decoder?
2. I am using the STM32F4 MCU and want to use stm32 hardware timer to measure the interval. Where do I create the timer instance? Is it a good idea to create one inside the decoding thread? Would the time count be accessible from the interrupt handler?
3. Also, where is a good place to call stm32_gpiosetevent function to register the handler for the EXTI pin event?

Thank you in advance!
Mike Smith
2014-03-20 18:03:06 UTC
Permalink
PPM decoding is best done using a timer in capture mode. Timing interrupt delivery will give you bad results without substantially more effort.

Sent from my iPhone
Post by f***@public.gmane.org
Hello,
I am working on a PPM decoder, part of a NuttX based project. I plan on using a specifically configured EXTI pin in order to capture PPM edges. In my vision, it would be best to use the external interrupt handler to write down the times, at which the edges were captured, form a "interval log" once the expected amount of pulses was captured, send this "interval log" to a specific PPM-decoding thread, and post a semaphore for this thread to decode it.
1. How do I exchange data between this interrupt-handler level and my thread, running the decoder?
2. I am using the STM32F4 MCU and want to use stm32 hardware timer to measure the interval. Where do I create the timer instance? Is it a good idea to create one inside the decoding thread? Would the time count be accessible from the interrupt handler?
3. Also, where is a good place to call stm32_gpiosetevent function to register the handler for the EXTI pin event?
Thank you in advance!
s***@public.gmane.org
2014-03-20 18:57:10 UTC
Permalink
Post by Mike Smith
PPM decoding is best done using a timer in capture mode. Timing interrupt delivery will give you bad results without substantially more effort.
There is an example of a timer used in input capture more in arch/arm/src/stm32/stm32_qencoder.c

There is also stm32_tim_getcapture() and the getcapture() method in arch/arm/src/stm32/stm32_tim.c, but there is no example usage anywhere in the source tree (and I have never used it).

Greg
Mike Smith
2014-03-20 19:25:42 UTC
Permalink
There is a PPM decoder as part of the high-resolution timer in the PX4 firmware:

https://github.com/PX4/Firmware/blob/master/src/drivers/stm32/drv_hrt.c
Post by s***@public.gmane.org
Post by Mike Smith
PPM decoding is best done using a timer in capture mode. Timing interrupt delivery will give you bad results without substantially more effort.
There is an example of a timer used in input capture more in arch/arm/src/stm32/stm32_qencoder.c
There is also stm32_tim_getcapture() and the getcapture() method in arch/arm/src/stm32/stm32_tim.c, but there is no example usage anywhere in the source tree (and I have never used it).
Greg
f***@public.gmane.org
2014-03-21 11:24:42 UTC
Permalink
Hello, Mike
Hello, Greg

Thank you for your answers. I see the PX4 way of doing things: every time you get an edge, you just use a handler to understand what part of PPM signal is being captured. Well, it might be a better idea, I'll give it a try.

However, I am still curious about the 3 questions I asked in the original post, I really hope I could understand NuttX architecture better and I need your help
s***@public.gmane.org
2014-03-21 13:53:15 UTC
Permalink
Post by f***@public.gmane.org
... However, I am still curious about the 3 questions I asked in the original post, I really hope I could understand NuttX architecture better and I need your help
1. How do I exchange data between this interrupt-handler level and my thread, running the decoder?
There is not one answer to this. This is really the core of the driver design. I suggest that you look at some of the existing drivers that do just this: Like serial, PWM, ADC, etc.

The solution will probably involve buffers, queues, and semaphores.
Post by f***@public.gmane.org
2. I am using the STM32F4 MCU and want to use stm32 hardware timer to measure the interval. Where do I create the timer instance? Is it a good idea to create one inside the decoding thread? Would the time count be accessible from the interrupt handler?
In the driver. I presume that you are going to create an PPM driver and this would be something that is inside of the driver. Look at at how other drivers do things like this: PWM and ADC would be good.
Post by f***@public.gmane.org
3. Also, where is a good place to call stm32_gpiosetevent function to register the handler for the EXTI pin event?
This is board specific logic that has to be done before the driver is configured. In NuttX, most drivers have an generic "upper half" and a platform-specific lower half. All GPIOs are, of course, platform specific and should be set in the platform-specific code in configs/some-board/src.

You can look at the PWM and ADC drivers. The upper half is in drivers/pwm.c and drivers/analog/adc.c, the lower halves are in configs/some-board/src/. The interfaces are defined in include/nuttx/analog/pwm.h.

You also might want to look at the touchscreen driver only because it uses GPIO interrupts just as you describe. The upper half drivers are in drivers/input and the lower halves are in in configs/some-board/src/. The touchscreen interface is defined in include/nuttx/input/touchscreen.h.

Greg
s***@public.gmane.org
2014-03-21 14:14:42 UTC
Permalink
I use an board with STM32F407IG (1 MByte of Flash, 192 Kbytes of SRAM) and an SPI Flash AT45DB041 (2MB). My app is about 220KB (and expecting to be bigger in the future), so it has to reside in internal flash. The SPI Flash would use SmartFS and the file would be transferred from PC to it using FTP.
That all sounds good to me.
The OS is Nuttx and the intention is to be able to build the application separated by the OS and be able to update it, without updating the system. I understand that this would require a kernel build and that kernel build is not very stable..
The Kernel build will support separate builds as you suggest. And it also appears stable on the platforms that I have tested with.

However, I would not necessarily recommend the kernel build in your case. The kernel build is used primarily to support security. It divides the flat build into two pieces: A kernel mode blob and a user mode blob. The MPU is then use to protect all of the kernel mode blob resources from the user mode blob.

If you want that kind of protection, then the kernel mode is exactly what you want. If you just want to build the application as a separate, replaceable blob then you don't need to use it. Consider this:

1. You can build the core OS and a loader as a separate NuttX application. Right? Nothing special here. NuttX would boot and start your loader application. The loader application would look to see if there is an application already in FLASH and, if so, it could just jump into it. The loader would have to know about some "magic" addresses where the application lies and you would probably have to have some header at that magic address so that the loader can determine if there is an application present there or not.

2. If there is nothing in FLASH (or, perhaps, if some special buttons are pressed at boot up time), then the loader could copy the application from the AT45 FLASH to the serial FLASH.

Now, how would you build an application in for this case? You would need only to have a special linker script that:

1. Does not include the NuttX startup and vector logic, and
2. Defines all of the symbols in the the base code. The syntax is like:

symbol = expression ;

And you use this a few hundred times to export all of the symbols from the base code. You would probably have to develop a tool that uses arm-none-eabi-nm or the top level System.map file to generate such symbol definitions. Then when you build the new application with this special linker script, it was call into the base code to interface with the RTOS.

An alternative would be to put a big call table in the base code that the application could use to access the base OS code. There are always many different designs that can achieve the same ends.

The only real advantage of the kernel build in your case is that that you can interface with the base code through traps and no such symbol information would be required.
I also have to be able to debug the app, while developing it with Atollic and J-link
I don't think that there is anything unique about this debug environment. If you have all of the symbolic information for that application, it should debug fine until you call into the base code, then you would have to load a different symbol file.
Is it possible (and how?) to build the app separated from Nuttx? Is it possible to update and execute it from internal flash ? Should I do this using /apps/system/install/ for this?
I have not used /apps/system/install, but it seems like it could be the basis for what you want to do.

Greg
pn_bouteville@yahoo.fr [nuttx]
2015-12-15 19:04:55 UTC
Permalink
Hi Greg,

There is some news about input capture ? I need to get value of timer when GPIO edge occur on multiple channels on one timer.

Pierre

Loading...