cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F769I-DISCO noise

benny
Associate II
Posted on June 19, 2016 at 01:46

Hi,

I want to ask if someone can confirm that the STM32F769I-DISCO has a high-pitched

https://www.dict.cc/englisch-deutsch/buzzing.html

https://www.dict.cc/englisch-deutsch/sound.html

. I think it's from the display unit. So this is normal or should i complain my board?

Kind regards

Nyix

#worst-forum-ever

Note: this post was migrated and contained many threaded conversations, some content may be missing.
23 REPLIES 23
benny
Associate II
Posted on February 21, 2017 at 11:45

Okay I want to solve the problem now for everyone who doesn't want to change the hardware / resistor.

As mentioned you can swap the 0 Ohm resistor from R1 to R5. In this case CABC has 3V3 and the display runs on full brightness.

With this idea (thanks so much J B !!!) I started to search for some more documents. For example the OTM8009A datasheet (the OTM8009A is directly connected to the LCD and generates the CABC signal). At page 65 section 5.2.36 you can find the command to set the display brightness (0x51h with one parameter in the range of 0x00h to 0xFFh).

Now we just need to send this command from the DSI to the OTM8009A. For this you can use two ways.

1)  

In the file otm8009a.c (Drivers->BSP->Components) at line 146

Change 'const uint8_t ShortRegData40[] = {OTM8009A_CMD_WRDISBV, 0x7F};'

To 

'

const uint8_t ShortRegData40[] = {OTM8009A_CMD_WRDISBV, 0xFF};'

This will set full brightness in the initialization and the noise will disappear.

2)

The file 'LCDConf_CmdMode_TE.c' provide the function 'void DSI_IO_WriteCmd(uint32_t NbrParams, uint8_t *pParams)'

After you call 'GUI_Init();' in your main-function or wherever you can do something like that:

Declare a variable like e.g. 'uint8_t lcd_brightness[] = {OTM8009A_CMD_WRDISBV, 0xFF};'

(OTM8009A_CMD_WRDISBV = 0x51h)

and call 'DSI_IO_WriteCmd(0, (uint8_t *)lcd_brightness);'

This will set the display brightness also to the maximum, but a short noise will appear in the start, because the brightness will initialize with 0x7Fh and is change some milliseconds after to 0xFFh.

I would prefer the first way. Change the driver and you never have this noise again. But you can experiment with the second solution and different brightness-level.

I hope this helps.

Hint: There are maybe some helpful other commands you want to send (e.g. display on/off) ! You can find them in the OTM8009A datasheet.

Kind regards

Nyix

Posted on February 21, 2017 at 12:14

Great stuff, Nyix! Thanks for completing this. Great teamwork!

Incidentally, did you happen to see a way to increase the frequency of the CABC signal, e.g. to 25 kHz, so that the brightness can be controlled without the audible noise problem?

JB.

Posted on February 21, 2017 at 12:35

Thanks. The datasheet says that the frequency for the CABC signal can be changed in the range of 38 Hz to 39 kHz. But I need some time to figure it out how to change it.

Edit: And I need to check if the LED-Driver can handle other frequencies.

Kind regards

Nyix

Posted on February 21, 2017 at 12:57

From https://www.st.com/content/ccc/resource/technical/document/datasheet/5b/92/e8/f8/41/e5/43/59/CD00098098.pdf/files/CD00098098.pdf/jcr:content/translations/en.CD00098098.pdf: 'The pin ENABLE can be used to dim the LED by applying a low frequency PWM signal'.

It also shows a graph (Fig 14) in which frequencies of 1 to 10 kHZ are used. I can't find an explicit upper frequency limit stated.

I don't want any audible noise in the 1 to 22 kHz range, and don't want any visual flicker below 200 Hz.

Therefore, I'm considering 200 Hz to 1 kHz and above 22 kHz.

There's no rush from my perspective as the one I'm using is already silent thanks to the resistor change. It's also a low priority for me because I'm happy with mine being always at full brightness. (It's not that bright).

At least we have a range of sensible and effective solutions.

Like you, I was not at all happy with the board when it was squealing. It's been really nice working with it since.

Incidentally, adjusting the brightness using PWM will likely reintroduce the problem of severe noise on the DAC output. If so, it's of limited use to me.

Thanks again.

JB.

Posted on February 21, 2017 at 13:42

Another option would be to dampen the mechanical oscillations by covering the offending component (probably L2) with some flexible glue.

benny
Associate II
Posted on February 21, 2017 at 20:36

Okay I get it working now.

So what to do step by step:

1) You need two pages from the OTMA8009A datasheet

Page 124 section 5.3.26 PWM_PARA3 (C6B1H) PWM Parameter 3

Page 127 section 5.3.28 PWM_PARA5 (C6B4H) PWM Parameter 5

2) In the beginning we should have a look at section 5.3.28 and the PWM_FREQ_SEL[1:0] parameter.

The default register value is 12h that means 0001 0010.  We only want to change the PWM_FREQ_SEL bits D2 and D1. The deafult value for D2 is 0 and for D1 1 (01).

With this information in mind we need to have a look at section 5.3.26. The default value here is 10h = 0001 0000 = 16 (dec). As you can see in the table with PWM_FREQ_SEL 01 and DBF 16 the PWM frequency is around 7.812 kHz.

3) More explanation: The LCD-Backlight-Driver has 5.5 microseconds as a minimum On-Time and 250 ns as the minimum Off-Time. That means if you want to dim the Backlight in 1% steps you need a maximum frequency of around 1818 Hz.

How to calculate: 1 / (100 steps * 5.5 micro seconds) = 1818 Hz.

For higher frequencies the resolution is greater than 1%.

So I tested 1.819 kHz this is in the table with the same PWM_FREQ_SEL value. Only the DBF value is raised from 16 to 72 (dec). But this makes noise too (not so loud). For lower frequencies you reach a better resolution so I tested 609 Hz (DBF = 217). There is still a bit noise, but not disturbing.

I decided to test higher frequencies with a resolution of 10% steps (that's totally fine for me). So I took DBF 6 this means 18.973 kHz. And the noise is gone (maybe not for my cat  )

3) Now I will explain how to write these values to the registers. The controller must be in command mode 2. This is only in the initialization.

3.1) You open the file 'otm8009a.c' and add 4 new variables (e.g.):

const uint8_t ShortRegData_PWM_FREQ_SEL_REGISTER[] = {OTM8009A_CMD_NOP, 0xB4};

const uint8_t ShortRegData_PWM_FREQ_SEL_VALUE[] = {0xC6, 0x12};

const uint8_t ShortRegData_PWM_FREQ_REGISTER[] = {OTM8009A_CMD_NOP, 0xB1};

const uint8_t ShortRegData_PWM_FREQ_VALUE[] = {0xC6, 0x06};

First I will tell you what does it mean:

You need to perform 2 operations. First set the register and second write the value.

To set the register we send the OTM8009A_CMD_NOP (=00h) and the last 2 bytes of the register address.

(e. g. section 5.3.26. the SPI/I2C/MDDI Address is C6B1h and has only one parameter so the last 2 bytes for the parameter are B1h)

Now we send the write instruction (C6h) and the value from the table, in my case 06h (= DBF 6 (dec) = 18.973 kHz).

3.2.) The DSI write command can be placed in the function

'uint8_t OTM8009A_Init(uint32_t ColorCoding, uint32_t orientation)'

between

'DSI_IO_WriteCmd( 15, (uint8_t *)lcdRegData24);'

and

'DSI_IO_WriteCmd(0, (uint8_t *)ShortRegData13);'.

That is before the comment with PWR_CTRL1.

In between you should place:

DSI_IO_WriteCmd(0, (uint8_t *)ShortRegData_PWM_FREQ_SEL_REGISTER);

DSI_IO_WriteCmd(0, (uint8_t *)ShortRegData_PWM_FREQ_SEL_VALUE);

DSI_IO_WriteCmd(0, (uint8_t *)ShortRegData_PWM_FREQ_REGISTER);

DSI_IO_WriteCmd(0, (uint8_t *)ShortRegData_PWM_FREQ_VALUE);

The first argument of DSI_IO_WriteCmd equals the number of parameter to write. 1 parameter = 0, 2 parameter = 1 etc.

4) Now you can test your code. I did it in this way:

Declare variables:

uint8_t lcd_brightness00[] = {OTM8009A_CMD_WRDISBV, 0x00};

uint8_t lcd_brightness10[] = {OTM8009A_CMD_WRDISBV, 0x19};

uint8_t lcd_brightness20[] = {OTM8009A_CMD_WRDISBV, 0x38};

uint8_t lcd_brightness30[] = {OTM8009A_CMD_WRDISBV, 0x4C};

uint8_t lcd_brightness40[] = {OTM8009A_CMD_WRDISBV, 0x66};

uint8_t lcd_brightness50[] = {OTM8009A_CMD_WRDISBV, 0x7F};

uint8_t lcd_brightness60[] = {OTM8009A_CMD_WRDISBV, 0x99};

uint8_t lcd_brightness70[] = {OTM8009A_CMD_WRDISBV, 0xB2};

uint8_t lcd_brightness80[] = {OTM8009A_CMD_WRDISBV, 0xCC};

uint8_t lcd_brightness90[] = {OTM8009A_CMD_WRDISBV, 0xE5};

uint8_t lcd_brightness100[] = {OTM8009A_CMD_WRDISBV, 0xFF};

Create an empty GUI Thread with

/* Initialize GUI */

GUI_Init();

WM_MULTIBUF_Enable(1);

GUI_SetLayerVisEx (1, 0);

GUI_SelectLayer(0);

GUI_SetBkColor(GUI_WHITE);

GUI_Clear();

and a loop like

while(1)

{

GUI_Exec(); /* Do the background work ... Update windows etc.) */

DSI_IO_WriteCmd(0, (uint8_t *)lcd_brightness00);

GUI_Exec();

osDelay(3000);

DSI_IO_WriteCmd(0, (uint8_t *)lcd_brightness10);

GUI_Exec();

osDelay(3000);

DSI_IO_WriteCmd(0, (uint8_t *)lcd_brightness20);

GUI_Exec();

osDelay(3000);

DSI_IO_WriteCmd(0, (uint8_t *)lcd_brightness30);

GUI_Exec();

osDelay(3000);

DSI_IO_WriteCmd(0, (uint8_t *)lcd_brightness40);

GUI_Exec();

osDelay(3000);

DSI_IO_WriteCmd(0, (uint8_t *)lcd_brightness50);

GUI_Exec();

osDelay(3000);

DSI_IO_WriteCmd(0, (uint8_t *)lcd_brightness60);

GUI_Exec();

osDelay(3000);

DSI_IO_WriteCmd(0, (uint8_t *)lcd_brightness70);

GUI_Exec();

osDelay(3000);

DSI_IO_WriteCmd(0, (uint8_t *)lcd_brightness80);

GUI_Exec();

osDelay(3000);

DSI_IO_WriteCmd(0, (uint8_t *)lcd_brightness90);

GUI_Exec();

osDelay(3000);

DSI_IO_WriteCmd(0, (uint8_t *)lcd_brightness100);

GUI_Exec();

osDelay(3000);

}

Remember because of the high frequency I can't scale with 1% so I took 10% steps.

This thread will step from 0 to 100% in 10% steps every 3 seconds.

Maybe ST will change the driver with the next release of the STM32F7Cube Library.

Edit: Feel free to test other frequencies as well

Edit 2: Seems like my cat can't hear anything too.

Kind regards

Nyix

Posted on February 22, 2017 at 16:06

For evaluation:

I attached a AC6 SW4STM32 project. You can simply import, build and flash it. The interesting parts are in otm8009a.c, k_lcd.h/.c and main.c.

Furthermore I attached the otm8009a datasheet (with some comments).

Edit: If someone is interested in: how to use SRAM and SDRAM for the heap with heap5.c. I used itin this example and explain it in another forum thread.

Kind regards

Nyix

________________

Attachments :

F769_lib1_6_otm8009a.7z.zip : https://st--c.eu10.content.force.com/sfc/dist/version/download/?oid=00Db0000000YtG6&ids=0680X000006Hysw&d=%2Fa%2F0X0000000bDa%2FkhNw6K.7TomtQoDJl2pT5e2XTxRBihAxBH1El6P5uKo&asPdf=false

OTM8009A-ORISE.pdf : https://st--c.eu10.content.force.com/sfc/dist/version/download/?oid=00Db0000000YtG6&ids=0680X000006Hysm&d=%2Fa%2F0X0000000bDZ%2FwZb_cuLXwKXo_nBlY70bjSqPgXzJd9Xb1uIguVW8vO8&asPdf=false

Posted on February 23, 2017 at 00:08

I'm nearly 49 so I probably can't hear ~ 19 kHz now. However, I could certainly hear up to 20 kHz when I was younger and also sense - as a sort of force / pressure near the sides on my head - frequencies just above that. Therefore, to accomodate younger people (as well as older people with intact hearing), I would like ST to use a frequency of at least 20 kHz and preferably above 22 kHz: particularly as it's almost certainly going to appear on the DAC output (as a consequence of the USB earth loop), just as the ~ 8 kHz did.

I understand that this would limit the number of brightness levels even further. Perhaps eight levels at around 22.5 kHz would be acceptable.

A frequency of around 200 Hz might be sufficiently quiet without introducing problematic flicker (I'm not in a position to try it right now). However, given the DAC interference issue, I doubt there's any merit in considering it unless the electrical noise / DAC output problem can be fixed.

All in all, particularly as I need the DAC output, my preferred option is still simply to use 100% brightness or display off.

Anyway, great work Nyix! I've not been able to download the files yet, I think due to some webhosting issue this end, but I'll try again tomorrow.

Cheers,

JB.

Posted on February 23, 2017 at 00:30

That approach would not solve the problem of the electrical noise that results from the PWM signal modulating the display backlight supply. As I mentioned above, with my setup this amounts to an absurdly high -39 dB. When the DAC output is fed to speakers, that's a seriously troublesome squeal.

If I power the board using a USB output battery pack - the sort used to charge phones etc - this drops to -90 dB, though obviously programming and debugging is then not possible. Another option might be to transformer couple the output e.g. using one of those isolation modules sold on eBay. A further option would be to use optical isolation, though that pushes the price up.

In any case, given the high volume and frequency of the sound, I'm doubtful that externally applied flexible glue would be sufficiently effective. However, I've got no hard evidence to support this view. Have you been successful doing this? If so, how successful and what glue did you use? (I'm interested because I've got other devices to silence).

Cheers,

JB.

Posted on February 23, 2017 at 09:42

I did a hearing test 2 years ago and I was able to hear up to 20 kHz. In my opinion the LCD is absolutely quiet with 18.973 kHz. But I forgot about your DAC problem. So I tested for you 22.135 kHz and 26.562 kHz. They are quiet as well and you are still able to dim. Everything you need to change is the DBF value from 6 to 5 (22k) or 4 (26k) according to the table.

If you can download the project then you need to change line 178 in otm8009a.c from

const uint8_t ShortRegData_PWM_FREQ_VALUE[] = {0xC6, 0x06};

to

const uint8_t ShortRegData_PWM_FREQ_VALUE[] = {0xC6, 0x05}; or 0x04

I have no equipment here to measure the DAC output, but 26 kHz nobody should hear. Or you make a clever trick and set the brightness to 100% if you play music and decrease it after.

Kind regards

Nyix

P.S.: Write me a PM if you still can't download, because for me it works now.