Closed ramenia closed 4 years ago
It looks like you use the high level u8g2 procedures with custom procedures for your hardware. However, speed will be influenced mostly on these hardware related procedures. Without knowing these hardware procedures I can not say whether speed improvements are possible.
Which gpio / byte level callback do you use?
I am not sure if i understand you correctly but this is my data transmit functions.
`void i2cScrWrite(uint8_t *writeBuff, uint16_t writeBuffSize)
{
HAL_I2C_Master_Transmit(&I2c.I2c, I2C_ADDRESS << 1, writeBuff, writeBuffSize, 2000);
}
uint8_t u8x8_byte_stm32l151_hw_i2c(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
static uint8_t buffer[32]; /* u8g2/u8x8 will never send more than 32 bytes between START_TRANSFER and END_TRANSFER */
static uint8_t buf_idx;
uint8_t *data;
switch(msg)
{
case U8X8_MSG_BYTE_SEND:
data = (uint8_t *)arg_ptr;
while( arg_int > 0 )
{
buffer[buf_idx++] = *data;
data++;
arg_int--;
}
break;
case U8X8_MSG_BYTE_INIT:
/* add your custom code to init i2c subsystem */
break;
case U8X8_MSG_BYTE_SET_DC:
/* ignored for i2c */
break;
case U8X8_MSG_BYTE_START_TRANSFER:
buf_idx = 0;
break;
case U8X8_MSG_BYTE_END_TRANSFER:
i2cScrWrite(buffer, buf_idx);
break;
default:
return 0;
}
return 1;
}
uint8_t stm32l1_gpio_and_delay_cb(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
switch (msg)
{
case U8X8_MSG_GPIO_AND_DELAY_INIT:
break;
case U8X8_MSG_DELAY_MILLI:
break;
case U8X8_MSG_DELAY_I2C:
break;
case U8X8_MSG_GPIO_DC:
break;
case U8X8_MSG_GPIO_RESET:
break;
}
return 1;
}`
Looks good. You do use HW I2C. Maybe you can increase speed for your HW I2C until the display stops working.
If you still feel, that your code is slow, maybe there is some issue in using U8g2. Can you share some u8g2 code which you feel is slow?
Hmm, maybe this is the limit of ssd1327 because when i run this code, words begin to appear from top to bottom. I am trying to make them all appear at the same time. For example this code:
u8g2_SetFont(&u8g2, u8g2_font_ncenB14_tr);
u8g2_DrawStr(&u8g2, 0, 20, "Hello World!");
u8g2_DrawStr(&u8g2, 0, 60, "Hello World!");
u8g2_DrawStr(&u8g2, 0, 100, "Hello World!");
u8g2_SendBuffer(&u8g2);
Hm... but to me it looks like "HAL_I2C_Master_Transmit" might be too slow. But in general the SSD1327 is also very slow. It actually is 4-bit graylevel controller. U8g2 only supports black and white, but still has to transmit either 0b0000 or 0b1111, which means, that there amount of data is 4 times higher compared to a true monochrome display.
For example the new grove display V2 includes a different controller than the SSD1327, which is much faster: https://www.seeedstudio.com/Grove-OLED-Display-1-12-V2.html
So one main reason for the poor speed is the display itself.
Thank you very much for your quick responses. I just want to ask one more question. Why words begin to appear from top to bottom is it because of the u8g2 or screen ?
Well, the transfer has to start somewhere, which is the upper left corner in case of U8g2. The screen is organized in pages, where each page has the height of 8 pixel ( see the SSD1327 datasheet). So u8g2 indeed starts with the first page. That means, the top 8 rows get transfered first. Within one page the data is transfered from left to right (like a progress bar with 8 pixel height).
Hi again, sorry to bother you again :) i have made a basic calculation which is my i2c speed is 400kHz. My screen is 128x128 also 4bit so 1281284 = 65536 / 400.000 = 0.163 second should be the time i need to send full screen buffer but i have made all the suggested changes for speed boost but still 0.435 second the best i got.
And there is a line in the code as / u8g2/u8x8 will never send more than 32 bytes between START_TRANSFER and END_TRANSFER / I can send much more bytes at the same time, why limit ?
And there is a line in the code as / u8g2/u8x8 will never send more than 32 bytes between START_TRANSFER and END_TRANSFER / I can send much more bytes at the same time, why limit ?
bigger data is internally split into smaller pieces.
my i2c speed is 400kHz.
Are you sure? Similar display with this controller did not support 400kHz.
but still 0.435 second the best i got.
Three points:
Is there a way to convert data from one bit/pixel to 4 bit per pixel before sendbuffer ?
Maybe, but will it help? U8g2 is a monochrome graphics lib, so somewhere you have to convert the data. Code is here: https://github.com/olikraus/u8g2/blob/21f5a74dff0d658a49d407fc5cd46ebdeea464f8/csrc/u8x8_d_ssd1327.c#L97-L125
Actually i want to make all preparations before "sendBuffer" and with sendBuffer i want to send everything those i want to see on the display with one and only buffer for once if ssd1327 can work like this. Can it ? or at least use bigger buffers not 32 byte maximum.
Actually i want to make all preparations before "sendBuffer"
Then you need to write your own graphics lib (or extend u8g2 a lot).
The focus of u8g2 is to make monochrome displays work. I mean focus is on functionality, goal is to support as many displays as possible. It is not like this, that I didn't care about speed (the opposite is true: I spent a lot on speed optimization), but I never sacrificed the u8g2 software architection for speed optimization of a special display with a very special internal memory architecture.
The point is this: Each display might have a different internal memory architecture to represent the graphics buffer.
On the other side, I have to decide for one specific memory architecture to do the u8g2 graphics functions. It is like this:
Graphics Functions --> U8g2 Graphics Memory --> Display Specific Transformation --> Display Graphics Memory.
In order to have a universal library which fits to (hopefully) all displays, there must be a transformation function to simplify the complexity of the tool. What you request is this:
Graphics Functions --> display specific drawing procedures --> display specific graphics memory --> Display Graphics Memory.
But this request is a complete different library.
Hi,
I am using
STM32L152
and have enough ram to does not care memory usage. I couldn't dig the code enough yet but it is like the library sends buffer divided. I am usingu8g2_Setup_ssd1327_i2c_midas_128x128_f
Thank you.