RoCorbera / BlueVGA

VGA library for STM32F103C (BluePill) that can manipulate a screen with 28x30 tiles with 8x8 pixels each, in a total resolution of 224x240 pixels with 8 colors using a very low footprint
Other
62 stars 12 forks source link

CRT VGA Monitor Image Problem & Fake Bluepill Issues #4

Open ComputerSongs opened 4 years ago

ComputerSongs commented 4 years ago

Hello, I have a problem with the signals. The image is distorted in some horizontal lines.

20201122_164817

I confirm that the problem is in the Sync signals, because shorting any color signal with the horizontal Sync signal, the image is also distorted.

20201122_170337

I tried other sketches and libraries, and they worked correctly, I tried to program the microcontroller with both cores, changing the bootloaders, trying another Blue Pill, but I couldn't get it to work.

For some reason, the problem is slightly greater when there are more colors displayed on the screen.

Any help is appreciated.

RoCorbera commented 4 years ago

Hello,

I can tell from your picture that you are using a very old CRT VGA Monitor. I've never tested the project using such monitor because I don't have one.
Thanks for sharing this issue.

All testing I have done was using modern LCD VGA Monitors and TVs with VGA input. What is the VGA Monitor you are using?

Some possible actions to "debug" the problem:

1) The bluepill must have a reliable power source with a good grounding.

2) Make sure your VGA monitor is working fine. Test it with a PC to check it.

3) Test the project on other VGA Monitor model in order to verify the repetition of the problem.

4) As this monitor is old, it may have very low timing variance tolerance. The STM32F103 is not perfect. There are clocking and memory reading micro delays, beside it may start a scanline IRQ with one or two cycles difference from each other causing the horizontal distortions you are seeing.

My suggestion is that you can try to play with some numbers that set the Horizontal timing in order to find a suitable value for your CRT VGA Monitor. It may work, but I'm not sure.

In bluevgadriver.c file in line 222 - it has to do with the total time of a single scanline: TIM1_REG->ARR = 2287; ===> maybe 2288 or 2289? Try changing the value 2287 by +1 or -1 to maybe solve the problem. You can test from 2277 to 2297...

The line 223 has to do with HSync timing. Try to chage this value ... maybe the issue is there. TIM1_REG->CCR2 = 142; ===> to be precise, should be 275 - already commited to the repository

The timing is calculated by this process:

Another alternative to try to solve this issue is playing with the final binary generated by changing the Compile Optimization -Os (Smallest - default), -O1, -O2, -O3. This can be done in the Arduino IDE menu: Tools --> Optimize (menu option).

Let me know if those actions can help you!

RoCorbera commented 4 years ago

Another possible solution related to using an old CRT VGA Monitor is that you must use the 330R resistors to connect to the VGA monitor port.

Are you using these resistors? It may be especially important when using a CRT Monitor.

Usage: Bluepill PIN ---> 330R resistor --> VGA Monitor input signal A 330R resistor will keep the output voltage under 0.7V for the Monitor.

ComputerSongs commented 3 years ago

Thanks for your help. I applied every solution he gave me, and what directly affects the problem is: 1 The value of TIM1-> ARR .. 2 The value of TIM1-> CCR2. 3 The compile optimization.

The monitor works perfectly, and I tried connecting my LCD monitor, the same LG monitor in the README.md image, and it shows exactly the same, also, something for which I frequently use these CRT monitors, is their tolerance to refresh rates greater than 75 Hz, and its large number of display modes.

The best configuration I managed so far is: 1 TIM1-> ARR = 2288 2 TIM1-> CCR2 = 275 3 Compile optimization: Fastest (-O3)

I haven't completely fixed the problem yet, but at least the text can be read well. This is a bit strange, maybe TIMER 1 is too vulnerable to small crystal oscillator clock errors, because the above setting works for one of my Pills, but not the other one, and a CrudeVGA sketch that produces the same mode display with the same frequency, but only using Timer 4, and it works perfectly, and even making changes to resolutions.

RoCorbera commented 3 years ago

I think that it has to do with the electronics and software of the monitor. I have an LGE Flatron L1752s and another older LCD monitor. The image is perfect when using the Flatron, but the scanlines use to oscillate visually using the oldest monitor.

It has to do with the fact that the software of modern monitors runs at 10 or more times the VGA clock rate and they are able to automatically adjust timing imprecisions coming from the VGA signal generated by the STM32F103.

There is also the detail related to the pixel clock frequency that is not the same that STM32F103 is changing its RGB pixels. For some VGA monitors it may cause a slightly blurring screen with a little pixel oscillation.

Thus, I think it won't run 100% perfect on every VGA monitor...

In my opinion, the best to do will be to use a modern LCD VGA monitor or TV. I understood that you also tested this same Flatron monitor in the picture from READ.md. It worked fine, right?

CrudeVGA uses the same principle, but it generates Sync signals from an IRQ instead of using Timer direct output to the pins. One issue I see clearly in CrudeVGA is that its "big chunk pixels" are never vertically aligned ... that's just a proof of concept.

What other problem are you seeing? Can you post a picture? Let me know about your thoughts and results. Thanks!

RoCorbera commented 3 years ago

Don't forget to use the 330R resistors! I tested once a while ago this project with a VGA projector and I noticed it had sort of overflown the pixels to the lateral border of the screen. I added the resistor to limit the voltage to 0.7 and the issue was solved.

ComputerSongs commented 3 years ago

Hi. I have good news, I already got it to work. After several tests I came to the conclusion that the problem was when using the GPIOC pins, so what I did was edit lines 179 and 215 to use the GPIOB pins, and it already works perfectly, only a small variation in size of pixels when many colors are present on the screen, but the problem is solved.

ComputerSongs commented 3 years ago

It also works fine with the GPIOA pins, but I didn't want to use these, because I need them to connect other things. Apparently the GPIOC pins of my microcontrollers do not work well at high frequencies.

EtienneGomide commented 3 years ago

Hi,

I have problems with image generation too, and after Rodrigo's solution to change video gpio output the problem has gone. Rodrigo think the problem is the stm hardware I have... Maybe not a original bluepill

Em sáb, 28 de nov de 2020 3:37 PM, ComputerSongs notifications@github.com escreveu:

It also works fine with the GPIOA pins, but I didn't want to use these, because I need them to connect other things. Apparently the GPIOC pins of my microcontrollers do not work well at high frequencies.

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/RoCorbera/BlueVGA/issues/4#issuecomment-735274370, or unsubscribe https://github.com/notifications/unsubscribe-auth/AOLYHQNZGWIQ2GGMPXDTIMLSSE7QBANCNFSM4T6WF5AA .

RoCorbera commented 3 years ago

I have about 10 different Bluepill boards here with me. I probed everyone using GPIOC as in the original code. All of them worked fine.

I think that the code on BlueVGA github is an excellent way to find out if you have got a fake Bluepill....

There are many Chinese clones of the STM32F103 being sold in the market. In my opinion, the problem you both are facing is related to a counterfeit STM32 chip.

For more information about Bluepill counterfeiting:

https://hackaday.com/2020/10/22/stm32-clones-the-good-the-bad-and-the-ugly/ https://github.com/keirf/Greaseweazle/wiki/STM32-Fakes https://www.stm32duino.com/viewtopic.php?t=127

EtienneGomide commented 3 years ago

Hello, I buy two more bluepills to test. Hope this time I have no fakes anymore. :-D

On Mon, Nov 30, 2020 at 10:52 AM RoCorbera notifications@github.com wrote:

I have about 10 different Bluepill boards here with me. I probed everyone using GPIOC as in the original code. All of them worked fine.

I think that the code on BlueVGA github is an excellent way to find out if you have got a fake Bluepill....

There are many Chinese clones of the STM32F103 being sold in the market. In my opinion, the problem you both are facing is related to a counterfeit STM32 chip.

For more information about Bluepill counterfeiting:

https://hackaday.com/2020/10/22/stm32-clones-the-good-the-bad-and-the-ugly/ https://github.com/keirf/Greaseweazle/wiki/STM32-Fakes https://www.stm32duino.com/viewtopic.php?t=127

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/RoCorbera/BlueVGA/issues/4#issuecomment-735798796, or unsubscribe https://github.com/notifications/unsubscribe-auth/AOLYHQMH6US3XZVVVWI5Z7TSSOPTVANCNFSM4T6WF5AA .

--

RoCorbera commented 3 years ago

Anyway.... the work around for this counterfeit Bluepill issue is to change the GPIOC to GCPIOA or GPCIOB ports as you wrote here. Doing so, RGB signals will move to ports GPIOA 13, 14, 15 or GPIO 13, 14, 15

Importat Note: GPIOA 13 and 14 are used for SWIO with STLink programming! It's highly recomended to use GPIOB istead.

In order to document such work around:

On bluevgadriver.c: Line 179 :: change GPIOC to GPIOA or GPIOB as below: For using GPIO A:

const uint8_t *GPIO __attribute__((aligned(32))) = (uint8_t*)(&(GPIOA_REG)->ODR);

For using GPIO B:

const uint8_t *GPIO __attribute__((aligned(32))) = (uint8_t*)(&(GPIOB_REG)->ODR);

Line 213 to 215 :: activate pin 13, 14, 15 on GPIOA or GPIOB instead of GPIOC: For using GPIO A:

  GPIOA_REG->CRH = (GPIOA_REG->CRH & 0x000FFF0F) | 0x333000B0;
  GPIOB_REG->CRL = (GPIOB_REG->CRL & 0xF0FFFFFF) | 0x0B000000;
  //GPIOC_REG->CRH = 0x33333333;

For using GPIO B:

  GPIOA_REG->CRH = (GPIOA_REG->CRH & 0xFFFFFF0F) | 0x000000B0;
  GPIOB_REG->CRL = (GPIOB_REG->CRL & 0xF0FFFFFF) | 0x0B000000;
  GPIOB_REG->CRH = (GPIOB_REG->CRH & 0x000FFFFF) | 0x33300000;