Discussion:
Mikroe-STM32F4 Touch panel architecture question
(too old to reply)
talkingtoken
2013-05-08 18:23:42 UTC
Permalink
Hi Greg,

I have an architecture question about implementing the touchpanel code on the Mikroe-STM32F4 board. I have studied the pic32mx7mmb touchpanel driver and schematic as a reference / starting point since it uses the same display and a very similar interface. The STM32F4 board adds driver circuits to drive the Left-Right and Top-Bottom voltages via to GPIO outputs, and it only has 2 ADC inputs to measure X and Y coordinates vs 4 on the PIC32MX7 board. This will mean some changes to the TP state machine, but that shouldn't be difficult.

The architecture question is this: Do you see any reason why I shouldn't use the existing STM32's ADC driver code within the touchpanel driver? I noticed the pic32 implementation makes direct ADC register reads / writes, but then it doesn't have a formalized ADC driver in it's arch/mips/src/pic32mx tree, only ADC header files. The Mikroe-STM32F4 board has 3 ADC channels, of which I could use #1 or #2 for the touchpanel inputs. The on-chip temperature sensor and Vbat measurement are connected to ADC channel #1 only. The board also has 7 ADC channels routed to the expansion I/O header, each of which could use either ADC #1/#2 or ADC #1/#2/#3. So I'm thinking for the implementation, I would use the ADC channels as such:

ADC #1: Touch panel, Chip temperature, Vbat
ADC #2: Reserved for use with expansion I/O
ADC #3: Reserved for use with expansion I/O

Is this the right approach for the architecture do you think, or should the touch panel driver interface directly with ADC channel #2 registers without going through the ADC driver, and then reserve ADC #1 and #3 for shared use for the other devices (on-chip and off-chip)? I guess the big question is if there are going to be any touch panel performance issues going through a driver with extra code to arbitrate multiple ADC requests (though temperature and Vbat requests likely wouldn't be active very often). But it would still mean extra code to execute vs. a few simple direct register accesses.

Thanks,
Ken
Gregory N
2013-05-08 19:06:54 UTC
Permalink
Hi, Ken,
Post by talkingtoken
I have an architecture question about implementing the touchpanel code on the Mikroe-STM32F4 board. I have studied the pic32mx7mmb touchpanel driver and schematic as a reference / starting point since it uses the same display and a very similar interface. The STM32F4 board adds driver circuits to drive the Left-Right and Top-Bottom voltages via to GPIO outputs, and it only has 2 ADC inputs to measure X and Y coordinates vs 4 on the PIC32MX7 board. This will mean some changes to the TP state machine, but that shouldn't be difficult.
This sound like improvements in the design. I never got the touchscreen working properly on the PIC32MX7. My recollection is that the touchscreen kind of worked in one quadrant, but not in others. I blamed the lack of driving circuitry at the time; I suspected that the GPIO outputs just couldn't source sufficient current. But that was just a superstitious belief; I never proved that.
Post by talkingtoken
The architecture question is this: Do you see any reason why I shouldn't use the existing STM32's ADC driver code within the touchpanel driver? I noticed the pic32 implementation makes direct ADC register reads / writes, but then it doesn't have a formalized ADC driver in it's arch/mips/src/pic32mx tree, only ADC header files. ...
Given the existence of the driver, I would consider using it. The only disadvantage that I can think of is that the ADC driver is more complex than some kind of simple, inline, hand-rolled logic. The STM32 has a lot of ADC features and the driver tries to expose those capabilities.

The STM32 ADC driver is "bottom half" driver. The top half is drivers/input/adc.c. The bottom half exports a standard ADC interface and the top half turns the ADC into a character driver that you can access with open, close, read, write. You can also use apps/examples/adc to verify your sampling logic.

If you look at the adc_read() function there, you can see that ADC samples are captured asynchronously from the device driver read operation. A lot of the ADC logic deals with timed sampling and other kinds of triggering. I'm not sure how it would support synchronous, sample-on-demand like the PIC32MX version of the driver -- perhaps with an ioctl?

Timed sampling could be a good design for a touchscreen interface. When the screen is touched, you can kick off the timed sampling then read, smooth, and threshold the data periodically. You need to do this kind of periodic sampling to detect "drag" operations and missed "pen up" events. Most touchscreen drivers do this timed sampling with an OS timer. Timed ADC sampling in this case could be pretty slick.

But I am not sure how that could integrate with the the output driving logic that has to go with the sampling.
Post by talkingtoken
ADC #1: Touch panel, Chip temperature, Vbat
ADC #2: Reserved for use with expansion I/O
ADC #3: Reserved for use with expansion I/O
That is a lot of ADC resources to use for one device. But if you have no other use for them, why not?

On the other hand, the STM32 is capable of sampling multiple pins, so you could use ADC#1 and get all three values on each sample. DMA is required to do that, however; the sampling is too fast to get more than one sample with interrupt driven logic. It looks like there is DMA logic in the driver now to support that.

But I have not used the ADC driver in some time (and there was no DMA support then). So perhaps someone else in this list could give you better advice than I can.
Post by talkingtoken
Is this the right approach for the architecture do you think, or should the touch panel driver interface directly with ADC channel #2 registers without going through the ADC driver, and then reserve ADC #1 and #3 for shared use for the other devices (on-chip and off-chip)? I guess the big question is if there are going to be any touch panel performance issues going through a driver with extra code to arbitrate multiple ADC requests (though temperature and Vbat requests likely wouldn't be active very often). But it would still mean extra code to execute vs. a few simple direct register accesses.
I would not think that touchscreen performance is an issue. The data rates should not be high (in fact, you want to keep the data rates down). You really only need sample data at rates a little less than 100 MSec to get smooth touch and drag kinds of operation.

I think that coordinating the driving and sampling logic would be the most complex part if you use the NuttX ADC driver.

Greg
talkingtoken
2013-05-08 20:57:45 UTC
Permalink
Hi Greg,
Post by Gregory N
This sound like improvements in the design. I never got the touchscreen working properly on the PIC32MX7. My recollection is that the touchscreen kind of worked in one quadrant, but not in others. I blamed the lack of driving circuitry at the time; I suspected that the GPIO outputs just couldn't source sufficient current. But that was just a superstitious belief; I never proved that.
This sounds reasonable, and is somewhat validated by MikroElektronica's changes to their newer boards which have all added external drive transistors for the touch panel.
Post by Gregory N
The STM32 ADC driver is "bottom half" driver. The top half is drivers/input/adc.c. The bottom half exports a standard ADC interface and the top half turns the ADC into a character driver that you can access with open, close, read, write. You can also use apps/examples/adc to verify your sampling logic.
--snip--
I think that coordinating the driving and sampling logic would be the most complex part if you use the NuttX ADC driver.
Looking more closely at the top-half and bottom-halfs drivers, it is clear I would have to use only the bottom-half portion, interfaced with the TP driver. But I would need to make changes to the bottom-half and add some conditional compilation based on TP configuration because of the need to control the DRIVE outputs, which would muddy the nice layering that exists in the code.

Looks like the right approach is to just hand-roll some code to directly use ADC2 (likely copied from the bottom-half ADC driver), and add a compile-time error if both TP and ADC2 are selected.

Ken
Gregory N
2013-05-08 21:33:34 UTC
Permalink
Post by talkingtoken
Post by Gregory N
The STM32 ADC driver is "bottom half" driver. The top half is drivers/input/adc.c. The bottom half exports a standard ADC interface and the top half turns the ADC into a character driver that you can access with open, close, read, write. You can also use apps/examples/adc to verify your sampling logic.
--snip--
I think that coordinating the driving and sampling logic would be the most complex part if you use the NuttX ADC driver.
Looking more closely at the top-half and bottom-halfs drivers, it is clear I would have to use only the bottom-half portion, interfaced with the TP driver. But I would need to make changes to the bottom-half and add some conditional compilation based on TP configuration because of the need to control the DRIVE outputs, which would muddy the nice layering that exists in the code.
Looks like the right approach is to just hand-roll some code to directly use ADC2 (likely copied from the bottom-half ADC driver), and add a compile-time error if both TP and ADC2 are selected.
I would not want to smear functionality or implementation across interface boundaries. I don't see any need to pervert a complex interface to support different a simple behavior. If there are special touchscreen behaviors you need that are not general ADC capabilities, my preference would be to create a different ADC bottom half altogether rather than disrupting the interfaces.

For example, I don't think you have any real use for all of the ADC triggering and interrupting logic in the current lower half. You just need to set up the conversion, perhaps delay a bit, and read the result of the conversion. That is a trivial bit of logic and not worth major changes to the existing ADC interfaces. That would better be handled by separate logic that, perhaps, derives in part from stm32_adc.c.

What you really need is a simple set of ADC library functions (to aid portability).

We should talk more once you understand the interface requirement changes.

Greg
talkingtoken
2013-05-08 22:18:11 UTC
Permalink
Hey Greg,
Post by Gregory N
I would not want to smear functionality or implementation across interface boundaries. I don't see any need to pervert a complex interface to support different a simple behavior. If there are special touchscreen behaviors you need that are not general ADC capabilities, my preference would be to create a different ADC bottom half altogether rather than disrupting the interfaces.
For example, I don't think you have any real use for all of the ADC triggering and interrupting logic in the current lower half. You just need to set up the conversion, perhaps delay a bit, and read the result of the conversion. That is a trivial bit of logic and not worth major changes to the existing ADC interfaces. That would better be handled by separate logic that, perhaps, derives in part from stm32_adc.c.
What you really need is a simple set of ADC library functions (to aid portability).
We should talk more once you understand the interface requirement changes.
Totally agreed on all points. I have modified the configs/mikroe-stm32f4/src/up_touchpanel.c file to pull out all the pic32 register accesses, add support for controlling the DRIVEA and DRIVEB outputs to energize the touchpanel, and updated the worker queue state machine so it only performs one y-axis sample and one x-axis sample (vs x+, x-, y+ and y- like it was doing with pic32mx7). I have the stub functions show below to implement, each of which could implemented as a library function instead:

tc_adc_init: Initialize the ADC to a the required mode for operation.
tc_adc_start_sample: Start sampling of the specified channel (Ch8 or Ch9 in this case)
tc_adc_read_sample: Read the result of the specified channel (wait if not complete)

As you mentioned, very trivial bits of logic that don't justify major changes to the existing ADC interface. If these are implemented with just 3-5 lines of code in the touch panel driver itself, then no more info is needed other than the channel number. As general library functions, they would need additional parameters, such as ADC channel number, resolution, sampling time, etc.

Ken
Gregory N
2013-05-08 22:34:33 UTC
Permalink
Hi, Ken,
Post by talkingtoken
Post by Gregory N
I would not want to smear functionality or implementation across interface boundaries. I don't see any need to pervert a complex interface to support different a simple behavior. If there are special touchscreen behaviors you need that are not general ADC capabilities, my preference would be to create a different ADC bottom half altogether rather than disrupting the interfaces.
For example, I don't think you have any real use for all of the ADC triggering and interrupting logic in the current lower half. You just need to set up the conversion, perhaps delay a bit, and read the result of the conversion. That is a trivial bit of logic and not worth major changes to the existing ADC interfaces. That would better be handled by separate logic that, perhaps, derives in part from stm32_adc.c.
What you really need is a simple set of ADC library functions (to aid portability).
We should talk more once you understand the interface requirement changes.
tc_adc_init: Initialize the ADC to a the required mode for operation.
tc_adc_start_sample: Start sampling of the specified channel (Ch8 or Ch9 in this case)
tc_adc_read_sample: Read the result of the specified channel (wait if not complete)
As you mentioned, very trivial bits of logic that don't justify major changes to the existing ADC interface. If these are implemented with just 3-5 lines of code in the touch panel driver itself, then no more info is needed other than the channel number. As general library functions, they would need additional parameters, such as ADC channel number, resolution, sampling time, etc.
Makes perfect sense to me. Is this portable logic that deserves to be abstracted and made available for other purposes?

It sound like not.

I have done the same kind of thing with, for example, the LCD backlight: By using some very simple PWM controls, you can manage the backlight level.

The canonically correct stm32_pwm.c driver is just to complex for something so simple.

You may need to do the same to control your LCD's backlight level. See, for example, logic in configs/stm3210e-eval/src/up_lcd.c that is conditioned on CONFIG_LCD_PWM. There the LCD setpower method controls the duty of the PWM output to the backlight GPIO.

Greg
talkingtoken
2013-05-10 23:15:03 UTC
Permalink
Hi Greg
Post by Gregory N
Post by talkingtoken
As you mentioned, very trivial bits of logic that don't justify major changes to the existing ADC interface. If these are implemented with just 3-5 lines of code in the touch panel driver itself, then no more info is needed other than the channel number. As general library functions, they would need additional parameters, such as ADC channel number, resolution, sampling time, etc.
Makes perfect sense to me. Is this portable logic that deserves to be abstracted and made available for other purposes?
It sound like not.
Well, I have the touchscreen driver for the Mikroe-STM32F4 port working now using a few direct ADC calls in the code, and it seems to work well. Now I'm trying to get nxwm working so I can do a real test other than debug prints of the X,Y coordinates. I tested it out successfully using the touchpanel example, so I expect things should work. I have all the NxWidget library compiled, along with the nxwm code and the CButtons UnitTest, but still haven't figure out how to get the test to show up under nsh (my favorite way to test things).

One thing I noticed is that there is no code in nxwm to deal with LCD orientation, so I'm guessing that's code I should add to the touchpanel driver?
Post by Gregory N
You may need to do the same to control your LCD's backlight level. See, for example, logic in configs/stm3210e-eval/src/up_lcd.c that is conditioned on CONFIG_LCD_PWM. There the LCD setpower method controls the duty of the PWM output to the backlight GPIO.
Yep, this was my plan, but had kinda forgotten about it until you mentioned it. Shouldn't be too hard to configure Timer 1/ Channel 1 to create a PWM output as needed to control the LED on this board.

Ken
Gregory N
2013-05-11 00:02:02 UTC
Permalink
Hi, Ken
Post by Gregory N
Post by talkingtoken
As you mentioned, very trivial bits of logic that don't justify major changes to the existing ADC interface. If these are implemented with just 3-5 lines of code in the touch panel driver itself, then no more info is needed other than the channel number. As general library functions, they would need additional parameters, such as ADC channel number, resolution, sampling time, etc.
Makes perfect sense to me. Is this portable logic that deserves to be abstracted and made available for other purposes?
It sound like not.
Well, I have the touchscreen driver for the Mikroe-STM32F4 port working now using a few direct ADC calls in the code, and it seems to work well. ...
I'm impressed. I thought that one would be trickier.
.... Now I'm trying to get nxwm working so I can do a real test other than debug prints of the X,Y coordinates. I tested it out successfully using the touchpanel example, so I expect things should work. I have all the NxWidget library compiled, along with the nxwm code and the CButtons UnitTest, but still haven't figure out how to get the test to show up under nsh (my favorite way to test things).
One thing I noticed is that there is no code in nxwm to deal with LCD orientation, so I'm guessing that's code I should add to the touchpanel driver?
No, nxwm doesn't build that way now. In the nxwm example, the NSH output appears an NxWM windows. So you type into your host PC terminal and the NSH output appears in the NxWM window (which I call an NxConsole window). Cute, but not very useful when the LCD is small.

There are a few screenshots here: http://tech.groups.yahoo.com/group/nuttx/files/NxWM%20Screenshots/ . Those are older. The current NwWM demo also has a calculater.

There might be complexities in getting the NxWM example to work as a NSH application that then runs NSH in NxConsole windows. I think it should be possible, but certainly also convoluted.

The NxWM main also just kicks off of some daemons and I/O managing threads and exits. So it is not much of a command line app (like x11start is not much of a command line app either). It is not a short example like the others, but instead instantiates a complete windows environment.

The NxConsole is an NX window that uses a special character driver for stdout and stderr that converts the output to a graphics text display. NxWM is a window manager and NxConsole is a terminal window analogous to an XTerm or an RXVT window.
Post by Gregory N
You may need to do the same to control your LCD's backlight level. See, for example, logic in configs/stm3210e-eval/src/up_lcd.c that is conditioned on CONFIG_LCD_PWM. There the LCD setpower method controls the duty of the PWM output to the backlight GPIO.
Yep, this was my plan, but had kinda forgotten about it until you mentioned it. Shouldn't be too hard to configure Timer 1/ Channel 1 to create a PWM output as needed to control the LED on this board.
No, it is not a lot of code. You use the MAXPOWER configuration and the new power setting in the setpower() method to control the duty: Full on is 100% and full off is 0% (but actually a special case because you should also turn the display off in that case)./

Greg
talkingtoken
2013-05-11 00:32:25 UTC
Permalink
Hi Greg,
Post by Gregory N
Well, I have the touchscreen driver for the Mikroe-STM32F4 port working now using a few direct ADC calls in the code, and it seems to work well. ...
I'm impressed. I thought that one would be trickier.
Thanks, but you already had most of it written ... I just changed up the ADC stuff and made a few small modifications to the state machine. Turns out I had to add about 12ms of "Settling time" between setting the DRIVE outputs and starting the A/D conversion, which makes perfect sense.
Post by Gregory N
No, nxwm doesn't build that way now. In the nxwm example, the NSH output appears an NxWM windows. So you type into your host PC terminal and the NSH output appears in the NxWM window (which I call an NxConsole window). Cute, but not very useful when the LCD is small.
There are a few screenshots here: http://tech.groups.yahoo.com/group/nuttx/files/NxWM%20Screenshots/ . Those are older. The current NwWM demo also has a calculater.
Okay, I setup to just run nxwm_main for now, and I got through the touchscreen calibration phase and to the main NXWM screen with the green "Start Arrow" and the background image. Wasn't getting anywhere after that, so I set a breakpoint in the CTouchscreen::listener routine to see if I was getting anything. Sure enough, the touchscreen driver is sending events, they are just being converted to astronomical scaledX and scaledY values, so I need to work through the calibration phase to find out what's going amis.

Ken

Loading...