Closed berndoJ closed 5 years ago
looks like no data is transfered. In the C code: Also the other delay messages need to be handled.
Hello,
thanks for the quick response olikraus.
So I've added the remainding delay messages (from the porting guide) to my C-code. (Attached) Then I've checked the data agin with an oscilloscope and sure enough, here's whats being sent on init (blue MOSI yellow SCK):
After all this the display shows the same random pixels.
But then, after checking the datasheet of the LCD to decode some of the messages sent on start, I noticed that the bytes should not be sent in 8 bit packets, but rather in 24 bit ones. I don't know if this may be the cause of my error, as I am always sending packets in 8 bits, not 24.
Regards, berndoJ
New u8g_stm32_port.c u8g2_stm32_hw_port.c.txt
looks like no data is transfered.
Can you check the CS signal line also?
It should change after some bytes of data and also there must be a delay between the last bit of the last byte and the level change of CS
Looking at your picture: It looks like high level is 3 Volt only. This is too less for the ST7920 which is a very old 5V IC.
Actually, the oscilloscope was set to 2V / Division, so the signal is 5V (there is a 74LVC4245APW voltage level translator between the STM32 and LCD). Here's a whole shot of the startup sequence, blue is CS and yellow is the clock (note that it is zoomed out very far to capture whole sequence, so the clock seems to only be a pulse, but actually its more short pulses.)
Here's the CS at the start of the sequence:
ok, at least one thing what is missing are the post cs and pre cs wait times: https://github.com/olikraus/u8g2/blob/master/csrc/u8x8_byte.c#L150
Additionally I suggest to set the CS level to a proper default: https://github.com/olikraus/u8g2/blob/master/csrc/u8x8_byte.c#L141
the other question also is: Did you apply the correct SPI mode? The ST7920 is a little bit sensitive for this.
So I've corrected the CS pre and post timing, added the defauklt state of the CS and corrected the SPI mode. Apparently the SPI mode of the ST7920 is 3, so I had to tweak my SPI settings a bit.
Now I am at a point where after calling my draw routine in display.c (unedited since last attachment) where usually a string should be drawn, the display is completely blank. (no random pixels, I can see it update to a blank screen after init).
I know that the display routine is run because of the output in the serial debug console.
Which setup did you use? How does your code look like?
This is my hardware setup:
LCD (12864B) connected: VCC to 5V0, backight to 3V3, VSS to GND; E to SPI SCLK R/W to SPI MOSI RS to SPI CS PSB to GND (Parallel / serial select)
SCLK, MOSI and CS are connected to the STM32 via a voltage translator (3V3 to 5V0, 74LVC4245APW) which has been tested and considered in working condition.
The contrast of the display is controlled with an onboard (on the LCD module PCB) potentiometer, and is tuned correctly. (See image in original post, the pixels can be seen)
The STM32 is set up using CubeMX software, which generates the code and configures the HAL library of the STM32.
As a debugger, a STLINKV2 is used.
The version of u8g2 was pulled from this GitHub repo on 17th of March 2019.
Here's the code:
display.c / display.h Here all the display drawing code is run. display_init function is called in init, display_run_thread is called after init, when FreeRTOS started the "thread" where I want the display code to be run. display.c.txt display.h.txt
u8g_arm.c / u8g_arm.h u8g_arm.c is the file containing all the necessary code for the hw port of the U8G2 lib to the STM32. u8g_arm.c.txt u8g_arm.h.txt
All display relevant code and / or code interfacing with the u8g2 library is contained within these two files and the assertion can be made, that display_init is called in init and display_run_thread after init from a thread from main.c.
Regards, berndoJ
ok, display.c looks good. What about the reset input of the display? The reset u8x8 reset message U8X8_MSG_GPIO_RESET
is not handled (did I miss this?). Then: What about the v0 input of the display. It should be connected to the wiper of a var pot to control the contrast.
So the V0 input is controlled via an onboard potentiometer (its directly on the lcd, measured it and it is connected to V0)
U8X8_MSG_GPIO_RESET
: I've added it to my code now. Nothing changed.
Hmm I am running out of ideas.
Yes, weird I know...
So I think I will check out if it makes a difference, if you send 24 bit blocks or 3 8 bit blocks to the ST7920 controller. Also, by reading various comments / blogs about the ST7920 a lot of people say that it is quite sensitive and tricky... Well, hope I'll fix it.
Just for info: This is a export of the data being sent. Basically, every time U8X8_MSG_BYTE_SEND
is called, it prints S-arg_int and then for each data byte D-data_byte_value. I know its long, but is it intentional to send individual 8 bit packets for example in init? (e.g. f8-30-80 is interpreted by the display as f83080 but is sent f8-30-80)
f8-30-80 is interpreted by the display as f83080 but is sent f8-30-80
not sure what you mean about this. What should be the difference?
if you send 24 bit blocks or 3 8 bit blocks to the ST7920 controller.
There is no other option. Arduino IDE only has a 8 Bit SPI interface, so it has to be 3x 8Bit. But this works quite well for my personal boards and displays.
Let me check your log:
[Kernel] Started serial port thread.
S-1
D-f8
[Kernel] Started util thread.
S-1
D-30
S-1
D-80
[Init] GPIO initialisation status OK.
Indeed the first init command for the display is 0x38: https://github.com/olikraus/u8g2/blob/master/csrc/u8x8_d_st7920.c#L50 This command must be sent as a 24 bit sequence (very inefficient, by the way): 0xf8 0x30 0x80
The conversion from 0x38 to the three byte sequence 0xf8 0x30 0x80 happens here: https://github.com/olikraus/u8g2/blob/master/csrc/u8x8_cad.c#L361
Except for the interrupting "Kernel" messages, the output sequence seems to be correct.
Also, by reading various comments / blogs about the ST7920 a lot of people say that it is quite sensitive and tricky... Well, hope I'll fix it.
I agree. Many requests here and on arduino.cc are problems related to ST7920 displays. It seems to be very sensitive regarding timing and wiring.
So I am curious:
I just checked the log again and I assume that every time 16 bytes are being transfered (so when S-10 (hex) is proceeding the data) pixel data is sent. But there is not single occurence of a non-zero byte in these 16 bytes after S-10. If my understanding is correct, doesn't this mean that the LCD displays a blank screen, because only null-bytes are sent to it? Or am I wrong?
If my understanding is correct, doesn't this mean that the LCD displays a blank screen, because only null-bytes are sent to it? Or am I wrong?
Yes, thats why I asked for the rest of your code. But this looks already ok:
u8g2_FirstPage(&u8g2);
do
{
u8g2_SetFont(&u8g2, u8g2_font_fur11_t_symbol);
u8g2_DrawStr(&u8g2, 0, 20, "Hello World!");
} while (u8g2_NextPage(&u8g2));
Maybe you could draw a box (drawBox) or a line (drawLine), just to ensure, that there are no other issues.
I've tried it with pixel sets and some rectangle graphics, but still nothing... Also, I've tried to set the draw color, but no effect.
This is the whole code:
So you say: The display becomes blank and all the data is zero in the log file. This means: The display works but some HAL procedure makes every to zero. Strange.
Oh, there is a "break" statement missing before "case U8X8_MSG_BYTE_END_TRANSFER:" Maybe this is your problem.
Ok, so here's whats happened:
So I've missed this one break statement, and sure enough, that fixed it. But the text wasn't showing, only a rectangle... So I've looked into it and i realised that I used a symbol font, not a normal font, so one small change and now the text also works. I also found out, that the display also runs with an SPI clock of 750kHz as well as default SPI-mode. (So default and 3)
I would say that the missing break statement was "ein absoluter Klassiker", if you know what I mean :)
Here's the working display:
Thank you for the extensive help olikraus, It is very appreciated from my side.
This issue is hereby closed.
Regards, berndoJ
"ein absoluter Klassiker"
tja...
I am happy that everything works :-)
I get same problem So, where is the "break" statement that youre fix it and where you change the "symbol font" to "normal font"?
Hello @olikraus, @berndoJ, please, which break statement were you guys referring to if your remember?
The missing break statement was in the µC port code in u8g_arm.c
(my code!!!) before case U8X8_MSG_BYTE_END_TRANSFER:
in the u8g_hw_port_byte_cb
function.
The file was linked in this comment:
This is my hardware setup:
LCD (12864B) connected: VCC to 5V0, backight to 3V3, VSS to GND; E to SPI SCLK R/W to SPI MOSI RS to SPI CS PSB to GND (Parallel / serial select)
SCLK, MOSI and CS are connected to the STM32 via a voltage translator (3V3 to 5V0, 74LVC4245APW) which has been tested and considered in working condition.
The contrast of the display is controlled with an onboard (on the LCD module PCB) potentiometer, and is tuned correctly. (See image in original post, the pixels can be seen)
The STM32 is set up using CubeMX software, which generates the code and configures the HAL library of the STM32.
As a debugger, a STLINKV2 is used.
The version of u8g2 was pulled from this GitHub repo on 17th of March 2019.
Here's the code:
* display.c / display.h Here all the display drawing code is run. display_init function is called in init, display_run_thread is called after init, when FreeRTOS started the "thread" where I want the display code to be run. [display.c.txt](https://github.com/olikraus/u8g2/files/2983943/display.c.txt) [display.h.txt](https://github.com/olikraus/u8g2/files/2983944/display.h.txt) * u8g_arm.c / u8g_arm.h u8g_arm.c is the file containing all the necessary code for the hw port of the U8G2 lib to the STM32. [u8g_arm.c.txt](https://github.com/olikraus/u8g2/files/2983966/u8g_arm.c.txt) [u8g_arm.h.txt](https://github.com/olikraus/u8g2/files/2983967/u8g_arm.h.txt)
All display relevant code and / or code interfacing with the u8g2 library is contained within these two files and the assertion can be made, that display_init is called in init and display_run_thread after init from a thread from main.c.
Regards, berndoJ
I see this issue linked in topics that frankly do not have anything to do with the issue at hand. The port of the u8g hw-interface was done according to the wiki docs, the issue was that I had that one break statement missing in my code, thus a unwanted switch/case fallthrough to the U8X8_MSG_BYTE_END_TRANSFER
section from U8X8_MSG_BYTE_SEND
.
Also, iirc, the symbol font thing was just a RTFM for me regarding on how to properly set up & use u8g2 in the code itself. I even attached the (working) code I've used in the previous answers:
void display_run_task(void)
{
debug_cons_println("[Display] Initialising display...");
u8g2_Setup_st7920_s_128x64_2(&u8g2, U8G2_R0, u8g_hw_port_byte_cb,
u8g_hw_port_gpio_delay_cb);
debug_cons_println(
"[Display] Initialised display communication over SPI.\n[Display] Initialising U8G2.");
u8g2_InitDisplay(&u8g2);
u8g2_SetPowerSave(&u8g2, 0);
debug_cons_println("[Display] Initialisation done.");
display_draw();
for (;;)
{
osDelay(500);
}
}
void display_draw(void)
{
debug_cons_println("[Display] Display draw routine init.");
u8g2_FirstPage(&u8g2);
do
{
u8g2_SetDrawColor(&u8g2, 1);
u8g2_SetFont(&u8g2, u8g2_font_fur11_t_symbol);
u8g2_DrawStr(&u8g2, 0, 20, "Hello World!");
u8g2_DrawPixel(&u8g2, 3, 3);
u8g2_DrawRFrame(&u8g2, 20, 15, 30, 22, 7);
} while (u8g2_NextPage(&u8g2));
debug_cons_println("[Display] Display draw routine done.");
}
Regarding other details I would really suggest you taking a look at the libraries docs in the GitHub wiki, this issue is already 5 years old and things may have changed during this time.
Cheers, berndoJ
@berndoJ thanks for your answer. I have access via cellphone only at the moment.
Hello,
so I've followed the porting guide (https://github.com/olikraus/u8g2/wiki/Porting-to-new-MCU-platform) on how to port u8g2 to a custom MCU platform. In my case I use an STM32F072RBT7 (ARM Cortex-M0 Core) STM32-MCU. It seems that my port of the hardware dependant functions at least kinda works, as data is pushed out over spi. (I checked it with an oscilloscope) The problem is that after the init of the display random pixels are displayed on screen, with 32 pixel wide white / inverted areas. (see image).
I use an 12864B 128x64 graphical LCD (I think its even the same one as in the SPI example of the setup tutorial), driven over SPI (SCK, MOSI, CS, RST), which uses the ST7920 LCD-Controller. As I've succeeded in driving this exact LCD with an Arduino before, this LCD is known good.
As firmware I use FreeRTOS and STM32CubeMX, which generates the HAL libs for my STM32 device.
I don't know if it is the issue of my hw port or if something different is going on...
Image of the LCD after init:
display.c : Here the u8g2 is initialised. display.c.txt
u8g2_stm32_hw_port.c : here are the functions used to port u8g2 to my device. u8g2_stm32_hw_port.c.txt
Thanks in advance, berndoJ