Jump to content

V21 Embest STM32F4-Discovery-BB mouse/button


wolf

Recommended Posts

Hi all,

i'm experiencing a problem with the mouse/button on a STM32F4-Discovery(407) and Embest baseboard + Embest LCD/touch

I'm using the supplied drivers for the STMPE811 touch IC.

The problem:

Having several button (i.e. 2 in opposite corners of the screen), the button just touched won't react upon the first touch, but on the second and any time after.

Most of the times the last button touched reacts once more, when a new button is touched.

I checked the mouse coordinates - they are OK when touched and released.

Is this a known issue?

Many thanks for looking into this. I'll do further investigations and will update the post in case i find a solution.

Greetings Wolf

EDIT:

I played around with the Settings in "ginput_lld_mouse_config.h":

I changed #define GINPUT_MOUSE_POLL_PERIOD from 3 -> 20

It's not quite perfect now, but much better now.

I'll do some more investigation - and once i have found the "perfect" Setting, I'll update this post again.

Thanks für now

Take care

Wolf

Link to comment
Share on other sites

Hello Wolf,

Sorry for our late reply but as we mentioned in the Announcement section we were not only for a couple of days.

Do you still have the problem? I took out my STM32F407-Discovery board with the same Embest baseboard + LCD module and everything works as expected here. Could you please attach your main.c (test case) and your gfxconf.h?

~ Tectu

Link to comment
Share on other sites

Hello Tectu,

1.)

well i'm on IAR Compiler, which you probably won't like too much. The main is just 2 Buttons in opposite corners of the Screen amd nothing else. The gfxconf is minimal for whats needed for a Standard button (no rounded corners or fanxy stuff at all)

I experienced the following:

When slowing down the System by assigning a counting breakpoint (IAR) on the button sending an event, the behavoiur got much better.

So i decided to slow down the GINPUT_MOUSE_POLL_PERIOD from 3 to 20 or even 50 and now it works pretty well - i.e. flawless.

Especially as the application got more complex in the meantime.

2.)

BTW: Another thing i observed: I took down the lcd backlight frequency from 1MHz to 20kHz and now you'll get a decend dimming with real steps. TheMHz is way too much on the enable for the switching Regulator.

3.)

I'll attach my Hobby application as a zipped s19 file:

I just uploaded the s19 file from the assembly with STM32 ST-Link Utility so the Win users should be able to store it into their (unmodified) HW likewise

What it is intended to do (might be intersting for all the ride by wire cars and motos around!):

It receives CAN Messages and takes the Contents apart in order to Display it on a 2 channel scope

You can specify the Offset of the value in the data lenght of (max 8) and specify how to Interpret these (u8, i8, u16, i16, u32, i32, flt32)

It has a modular soft menu that appears when you touch the graph surface

It has some scope Features as scaling and Offset....

It is quite self explaining and worked on a F103C8T6. Now i switched to the 407 on the discovery board

I didn't hook it up to a CAN line Driver yet, but it worked before on the F103 (i'll have to check all the AF stuff etc.)

It has a shell on the RS232 connector (UART6 @ 38400,n,8,1) - just give it an info to list the commands

The FLASH part, i.e. save and recall is commented out as it needs some Adaption to the F4 coming from F1

HowTo: tap the Screen in the graph area - hit the Demo button - hit On - you have a random Display. Play around

You'll see the button stuff is mostly OK now

Thanks für looking into it and even more congretulation for your great work - same for Giovanny

Wolf

CAN_SCOPE_DEMO.zip

Link to comment
Share on other sites

I have not specifically had much to do with that particular touch device however we used to have similar problems with the MCU touch driver. The reason ended up being due to spurious readings occurring across the touch event as the touch is being depressed or released. The workaround was to lower the polling rate (less chance of getting the reading during the indeterminate period). The fix was to not accept a reading until you had two readings in the same depression state.

I suspect that something similar is going on with your controller. I will look in the next few days.

At least it is operating acceptably for you currently.

Thanks also for the hint with the back light.

Link to comment
Share on other sites

  • 5 months later...

Hi all,

1.)

after a long period i dug out my EMBEST Hardware again and looked into the touch Problem.

Inmarket gave the hint of faulty readings in a different Setup, so i searched in this direction.

Watching the I2C signals on a scope showed, that the I2C frequency set to 400.00 kHz is way too high for the pullups used.

The clock and data Signal Timing leads to false readings, which in turn causes the Problem described above.

I reduced the Speed from 400.000 kHz to 200.000 kHz and the Signals look OK now - and more important the readings are correct now (in i2ccfg in ginput_lld_mouse_board.h)

BTW: Checking the drawings, I only found a 4k7 (R2) pullup resistor on SCL and none on SDA on the base board (there must be one on SDA too somewhere, otherwise it wouldn't work at all)

2.)

At the same time i reduced the poll Intervall to 50 (ms) in ginput_lld_mouse_config.h

3.)

As described in an earlier post, i reduced the PWM Speed on the LCD backlight from 1.000.000 to 20LHz to get a decent dimming (pwmcfg in board_SSD2119.h)

Other users reproted an audible ringing of the switching Regulator at lower enable/disable Speeds - I don't

@Tectu

If, as you said, it works perfectly fine on your Hardware, maybe there is a different HW Version in use. My HW is:

LCD: DN-LCD35RT 120700 V1.0

Base: DM-STF4BB 120601 V1.1

Anyway, it might be worth a check w/ the scope whether it is just working at ist Limits or it might be a good idea to reduce I2C Speed as described

Many thanks for your help,

best regards

Wolf

Link to comment
Share on other sites

Thanks for your work on this. Can you please post your updated board files and we will integrate the changes into the master repository?

Also the mouse testing, was that done against the current master. We have completely rewritten the mouse sub system since your previous post in June. The new system is much more tolerant of bad data and transitions.

The work you have done with frequency of the busses is fantastic and will be very helpful in getting great results. Thank you for your hard work.

Link to comment
Share on other sites

Hi all,

please find the updated board files attached!

I also changed the entry mode in gdisp_lld_SSD2119.c from AM=0 to AM=1 (see SSD2119 Manual):

// write_reg(g, SSD2119_REG_ENTRY_MODE, 0x6830); // ENTRY_MODE_DEFAULT !!!!

write_reg(g, SSD2119_REG_ENTRY_MODE, 0x6838); // ENTRY_MODE_DEFAULT

The reason is (when rotate 0):

I stream data via DMA from internal RAM to the Display. The RAM is organized as color_t framebuf[x][y] and now the address update direction corresponds.

Best regards

Wolf

SSD2119.zip

STMPE811.zip

Link to comment
Share on other sites

MORE TROUBLE resolved!

The Problem:

I ran into a new Problem when stressing the LCD with high Speed data coming from a DMA Transfer via dma_with_inc() in board_SSD2119.h.

Sometimes there were artefacts on the LCD belonging to the data in the DMA Transfer, but displayed on a different LCD area.

After check my code (which runs perfectly on a HY32D Display from HAOYU), I supposed that the commands Setting the RAM-window on the LCD might get corrupted.

After checking the CS and the WR Signal on the LCD, i found that the WR Signal was out of spec and generally not loking nice (ie. not rectangular) at all.

I looked rather like a R/C lowpassed rect signal

The reason (IMHO):

I hooked up the Display with the supplied ribbon cable of about 20cm length.

The cable capacitance and the inline 22R resistors to all the LCD signals together form a.m. lowpass and lead to the corrupted writes to the LCD.

The solution:

I gradually changed the FSMC settings in board_SSD2119.h until the Problem was gone (and gave it some reserve, i.e. 1 HCLK each - FSMC_BTR1_ADDSET and FSMC_BTR1_DATAST). See file attached!

Of course, the global LCD update time grew together with the increased address and data Setup times.

BTW: I run the F407 @ full Speed: HCLK = 168MHz

General remark:

As this is Hardware related stuff, not easily detectable w/ pure SW Tools, it might be a good idea to use a bit more prudent Setting in the demo files.

On top it all depends on the HCLK Speed, so a General remark for optimized Operation @ lower HLCK Speeds in the source code might be a good idea.

As for the Hardware cracks chasing for each ns (i belong to this species), the best way is to tune it up and Keep an eye on the scope!

Best regards

Wolf

SSD2119.zip

STM32F407-EMBEST-BB.zip

Link to comment
Share on other sites

Yes you are 100% correct.

Board files are always meant to be tweaked for the specific hardware and cable lengths etc to displays are often a critical factor.

In terms of initial settings, what tends to happen is that we (or someone else from the user base) gets a board file working on their hardware. That is then posted as the "reference" board file and it is only when someone else complains about it not working that it may be re - examined.

The main reason we don't perform a testing of conservative settings etc is just time. With ugfx there is just so much to do and Tectu and myself fit this around our normal work lives. In many cases we don't own the hardware as the driver/board files have been donated by a user (although I like to do a quality pass over the code before it makes the master repository).

It is for this reason that we so highly value your contribution in fine tuning these parameters to work on a much wider range of hardware. Without efforts such as yours ugfx would not be usable by a wide enough base of users.

Thank - you.

Your changes should make the master repository in the next few hours.

Link to comment
Share on other sites

Hi all,

@inmarket

Many thanks for your appreciation and fast reaction

At least I can contribute something to this great work of yours

And of course we're all very much committed to our work life!

So - ì will try the updated files from the latest master as soon as I get a few minutes - and i will Report

Best regards

Wolf

Link to comment
Share on other sites

@inmarket

Hi, I checked the changes in the latest master: Perfect!

BTW: the hard-core Change i made in LLDSPEC void gdisp_lld_fill_area(GDisplay* g), i.e. omitting the local variable c, had the following reason:

I use the main RAM area (most of it) as a Display buffer for the LCD (301 * 201 * 2 Bytes = 121.002 Bytes).

With little RAM left there, I activated the core coupled Memory for the thread working Areas (ChibiOs). The nasty side effect was, that the variable c was allocated on the thread stack in CCRAM (i.e. 0x1000xxxx). So far OK, but DMA can't Access this Memory on STM32F407, and calling the DMA fill area code stalls upon first transfer attempt

It took me some time, mainly reading the manual and debugging, to figure this out

This CCM seems to be an interesting topic when it comes to benchmarking.

I'll have to investigate this a bit in depth (A Mandelbrot w/ FPU and CCM comparison maybe).

I'll Report in a new thread, once something noteworthy Comes up.

So long

Wolf

Link to comment
Share on other sites

Yes interesting problem.

Removing the local variable means that the translation from user pixel format to driver pixel format doesn't occur. This ok if the pixel formats are the same (your case) but is not ok generally.

There is however a simple solution - make c a static variable. This can also be conditioned on the use of dma, and optionally a define indicating the use of ccr memory.

I will make the change to the master to reflect this (and in other drivers the can use dma too)

Link to comment
Share on other sites

The master has now been updated. Set the define GDISP_NO_DMA_FROM_STACK to TRUE in your board file to tell it to use main memory instead of stack space for the define.

By the way, why are you using main ram for a framebuffer? Ugfx should work without a framebuffer for the SSD2119 controller.

Link to comment
Share on other sites

Hi all,

@inmarket

1.) I'll try out the latest Master and will report

2.) Why use RAM as frame buffer?

I use the main RAM as frame buffer for speed reasons.

I implemented an intelligent draw/erase/add algorithm, using the current pixel value in order to calcualte the new pixel value.

I could use the video RAM of the SSD2119 and read back from there - which works perfectly well, but is significantly slower (about factor 10 - LCD read timing + address setting etc)

So i do it in the frame buffer in internal RAM (much faster) and transfer the framebuffer by DMA (little CPU load, if you make the (2 part 301*201 pixel) DMA non blocking - total about 8ms)

If you like to see what i mean by speed - just download the hex file from an earlier post in this thread to am EMBEST BB w/ LCD w/ STM32F407-Discovery if you have one at hand.

The current version gives about 50 fps for the scope area (if i remember right, can't check it right now) - flicker free. An I can do even more.

Best regards

Wolf

BTW: to achieve this, i made a scope class (deviated and stripped from graph) working on the frame buffer. All the rest (i.e. menu labels) work normally w/ uGFX functions

Link to comment
Share on other sites

If you like to see what i mean by speed - just download the hex file from an earlier post in this thread to am EMBEST BB w/ LCD w/ STM32F407-Discovery if you have one at hand.

The current version gives about 50 fps for the scope area (if i remember right, can't check it right now) - flicker free. An I can do even more.

We'd love to see a video of this - is it possible for you to make a public available one?

~ Tectu

Link to comment
Share on other sites

I just had a thought - have you seen the audio and/or the gadc demos. They similarly define a scope widget (although very basic) which demonstrates another way of doing it without a full frame buffer or even the ability to read pixel ram. It would be interesting to compare the approaches.

At the time I was developing on an Olimex SAMEX256 board with a Nokia6610GE8 display (a slow display with no pixel read capability).

Link to comment
Share on other sites

Hi all!

OK - I made a quick video. Sorry for the bad quality, i.e. focus. I'll try to make a better one and comment it, when I get hold of a decent camera.

It will be visible here:

http://youtu.be/WmpKC9ODH8c

The hard facts:

trace are update time is 8,2ms (DMA - still blocking, will be changed by using a bSem)

frame rate is about 30 Hz

uC load by the scope application (scopeapp) is about 43% - no optimization - see shell output below (@168 MHz)

The scopeapp handles everything, but the menu, i.e. trace generation and drawing, reference, trig pos & level, h & v cursors, top and bot info line, resizing ...

This is what I meant by fast - once you add an analogue frontend to it, you can make a decent pocket scope from it!

What do you think?

Best regards

Wolf

p.s. In an earlier attempt, I used the analogue watchdog function of the STM to handle the trigger whilst banging the ADC values by DMA into a ring buffer - worked perfectly

ch> thd
addr stack prio state name time %
20000AB0 2001FFA4 64 SLEEPING main 13 0%
20000528 2000058C 1 READY idle 392125 56%
200005E0 20000A0C 127 WTSEM (null) 194 0%
100009F8 10000B44 2 CURRENT shell 1 0%
10000328 10000634 66 SLEEPING menucursor 1 0%
10000000 100002CC 66 WTSEM menu 163 0%
100006D0 10000994 64 SLEEPING scopeapp 300459 43%
ch>

Link to comment
Share on other sites

Hi community,

many thanks for your appreciation.

@ Tectu & inmarket:

Please feel free to put the video on the demo page.

BTW: The fast draw/erase code is based on BenF's DSO code, so the credits go to him (Google).

In the original code was made for on an STM32F103, w/ no space for a RAM buffer of the size of the trace area (in assembler to speed things up).

So the internal RAM of the LCD driver is used as a frame buffer. This is OK for all LCD drivers allowing to read back the data in a pixel, i.e. internal RAM cell.

The working principle is as follows:

From the original color_t in 565 colour scheme there are a total of 6 bits reserved (3 x the 2 LSBs of each colour) as flag bits.

These bits cleared or set in a full colour like Cyan or Yellow won't be noticed by the human eye.

When defining the trace colour Cyan (CH2_COLOR) for example, the original Cyan will be anded w/ ~F_SELECT (the flag bits) and ored w/ CH2_FLAG (the flag bit for CH2 present) - See defines below


#define RGB(_R,_G,_B) (((_R & 0x3E) >> 1) | ((_G & 0x3f) << 5) | ((_B & 0x3e) << 10))
#define C_GROUP 0x1082
#define F_SELEC 0x18E3
#define GRD_FLAG 0x0040
#define LN1_FLAG 0x0020
#define LN2_FLAG 0x0800
#define CH1_FLAG 0x0080
#define CH2_FLAG 0x0002
#define REF_FLAG 0x1000
#define LN1_COLOR (RGB( 0,29,63) & ~F_SELEC) | LN1_FLAG
#define GRD_COLOR (RGB(32,32,32) & ~F_SELEC) | GRD_FLAG
#define LN2_COLOR (RGB(63,63,63) & ~F_SELEC) | LN2_FLAG
#define CH1_COLOR (RGB( 0,63,63) & ~F_SELEC) | CH1_FLAG
#define CH2_COLOR (RGB(63,63, 0) & ~F_SELEC) | CH2_FLAG
#define REF_COLOR (RGB(63, 0,63) & ~F_SELEC) | REF_FLAG

How does it work?

1.) Adding a trace (Cyan = CH2_COLOR) over an existing grid (Grey LN1_COLOR):

If on the pixel to be drawn there is already a grid dot, the new colour (Cyan) will be dawn, but the grid flag (LN1_FLAG) will be preserved

2.) Erasing the trace from 1.)

The whole trace (to be erased) is drawn again pixel by pixel, this time via an erase method. The pixel data is read back, the CH2_COLOR is anded out and the remaining flags are inspected. If the LN1_FLAG is present in these flags, the LN1_COLOR is restored etc.

Due to the order of handling in the erase method, there is a certain priority order in the different colors

3.) There is a drawing routine too, just banging a color_t to the frame buffer or LCD w/o regarding the flags

4.) Of course draw / add / erase are all handled by the same method w/ a flag set

Sounds complicated, but is pretty fast compared to erasing a whole display area (flicker on LCD, time consuming in frame buffer), redrawing a grid, redrawing the trace

Here you just have to erase the existing trace (you kept the trace data in RAM) and redraw the new trace - Way less pixel operations - and NO flicker.

This principle works in a frame buffer as well as in the display driver RAM. Frame buffer is much faster as display driver RAM accesses involve setting the display window, setting the cursor, most of the time a dummy read and a real read of the pixel data - adding up to easily 10 or more access operation @ FSMC speed (slower than internal RAM) if you are lucky or GPIO operations (much slower than internal RAM) when there is no FSMC (but still feasible)

That's the secret of it all, no sorcery to it.

@inmarket:

I'll PM you the code of my scope class for inspection. It's mainly a copy of the graph class working on a.m. principle and a frame buffer

@all:

For now this is not intended to be a commercial thing, but w/ the right digital frontend it might be a handy tool for other uGFX and embedded users.

Pricewise you are of course better of w/ a commercial solution as DSO 201 or better a cheap RIGOL scope - If you need one.

It's just for fun

So far for now,

Best regards

Wolf

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...