Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Timing Problem with KS0108 #493

Closed
roberto314 opened this issue Jan 27, 2018 · 22 comments
Closed

Timing Problem with KS0108 #493

roberto314 opened this issue Jan 27, 2018 · 22 comments
Labels
Milestone

Comments

@roberto314
Copy link

roberto314 commented Jan 27, 2018

This is not really a library problem - more an enhancement:
I measured the E - cycle time on a KS0108 display i have and i needed 2.8us! The datasheet says 450ns and in u8g2 the delay nano takes an 8-bit parameter (which is actually 200). Can't you change that to DELAY_100NANO so the parameter can be changed from 5 (which would be 500ns) up to 255 (which would be 25,5 us)?
Also i made a functonal framework to get u8g2 working with ChibiOS, could be interesting for the porting guide.
See: http://www.chibios.com/forum/viewtopic.php?f=8&t=4459

@olikraus
Copy link
Owner

You mean, I should change the meaning of this value from ns to 100ns:

I measured the E - cycle time on a KS0108 display i have and i needed 2.8us!

What does this mean? On your setup you measured this value? Or you figured out, that smaller values do not work?

You mean this value:
https://github.com/olikraus/u8g2/blob/master/csrc/u8x8_d_ks0108.c#L121
and your request is to modify the call here:
https://github.com/olikraus/u8g2/blob/master/csrc/u8x8_byte.c#L169

hmmm difficult... a lot of other displays are affected...

@olikraus
Copy link
Owner

Actually I agree to the discussion on chibios.com, that nano seconds are useless. At least I should use a U8X8_MSG_DELAY_10NANO msg instead.
Maybe I should change the message from U8X8_MSG_DELAY_NANO to U8X8_MSG_DELAY_10NANO and modify the values for all displays.

@roberto314
Copy link
Author

I had a setup with a Nucleo F401 @ 84MHz ARM and made accurate timings with chibios and a hardware timer. Checked with oscilloscope. After a lot of fiddling i figured out the 2.8us. In your previous post you mentioned the exact positions i would change too, but i think only KS0108 Displays are affected? With 10ns i one could only get a max. of 2.55us - too short for my KS0108 (maybe mine is extra slow?) but i could wait two times this value (just duplicate the call) which would be fine.

@olikraus
Copy link
Owner

the problem is, that the code is reused across many displays. I can not simply extend the range.

@roberto314
Copy link
Author

You can make a #define EXTENDED_RANGE for example. Set it to default = FALSE and if TRUE you can youse 10NANO instead of 1NANO. I also would suggest to extend even further to 2*10NANO.

@olikraus
Copy link
Owner

olikraus commented Jan 28, 2018

I see the following values at the moment:

u8x8_d_a2printer.c:  /* write_pulse_width_ns = */ 40,
u8x8_d_il3820_296x128.c:  /* write_pulse_width_ns = */ 150,	
u8x8_d_ist3020.c:  /* write_pulse_width_ns = */ 60,	/* IST3020 datasheet, page 54 */
u8x8_d_ks0108.c:  /* write_pulse_width_ns = */ 200,	/* KS0108: actially 450 ns */
u8x8_d_lc7981.c:  /* write_pulse_width_ns = */ 20,	
u8x8_d_lc7981.c:  /* write_pulse_width_ns = */ 20,	
u8x8_d_lc7981.c:  /* write_pulse_width_ns = */ 20,	
u8x8_d_ld7032_60x32.c:  /* write_pulse_width_ns = */ 40,	
u8x8_d_ls013b7dh03.c:  /* write_pulse_width_ns = */ 100,
u8x8_d_max7219.c:  /* write_pulse_width_ns = */ 150,	
u8x8_d_pcd8544_84x48.c:  /* write_pulse_width_ns = */ 40,
u8x8_d_pcf8812.c:  /* write_pulse_width_ns = */ 150,	
u8x8_d_sbn1661.c:  /* write_pulse_width_ns = */ 200,	/*  */
u8x8_d_sed1330.c:  /* write_pulse_width_ns = */ 220,		/* G242CX Datasheet p5 */
u8x8_d_sed1330.c:  /* write_pulse_width_ns = */ 220,		/* G242CX Datasheet p5 */
u8x8_d_sh1107.c:  /* write_pulse_width_ns = */ 150,	/* sh1107: cycle time is 300ns, so use 300/2 = 150 */
u8x8_d_sh1107.c:  /* write_pulse_width_ns = */ 150,	/* sh1107: cycle time is 300ns, so use 300/2 = 150 */
u8x8_d_ssd1305.c:  /* write_pulse_width_ns = */ 150,	/* SSD1306: cycle time is 300ns, so use 300/2 = 150 */
u8x8_d_ssd1306_128x32.c:  /* write_pulse_width_ns = */ 150,	/* SSD1306: cycle time is 300ns, so use 300/2 = 150 */
u8x8_d_ssd1306_128x64_noname.c:  /* write_pulse_width_ns = */ 150,	/* SSD1306: cycle time is 300ns, so use 300/2 = 150 */
u8x8_d_ssd1306_128x64_noname.c:  /* write_pulse_width_ns = */ 150,	/* SSD1306: cycle time is 300ns, so use 300/2 = 150 */
u8x8_d_ssd1306_64x32.c:  /* write_pulse_width_ns = */ 150,	/* SSD1306: cycle time is 300ns, so use 300/2 = 150 */
u8x8_d_ssd1306_64x48.c:  /* write_pulse_width_ns = */ 150,	/* SSD1306: cycle time is 300ns, so use 300/2 = 150 */
u8x8_d_ssd1306_96x16.c:  /* write_pulse_width_ns = */ 150,	/* SSD1306: cycle time is 300ns, so use 300/2 = 150 */
u8x8_d_ssd1309.c:  /* write_pulse_width_ns = */ 150,	/* SSD1306: cycle time is 300ns, so use 300/2 = 150 */
u8x8_d_ssd1309.c:  /* write_pulse_width_ns = */ 150,	/* SSD1306: cycle time is 300ns, so use 300/2 = 150 */
u8x8_d_ssd1322.c:  /* write_pulse_width_ns = */ 150,	/* SSD1322: cycle time is 300ns, so use 300/2 = 150 */
u8x8_d_ssd1322.c:  /* write_pulse_width_ns = */ 150,	/* SSD1322: cycle time is 300ns, so use 300/2 = 150 */
u8x8_d_ssd1325.c:  /* write_pulse_width_ns = */ 60,	/* SSD1325 */
u8x8_d_ssd1326.c:  /* write_pulse_width_ns = */ 60,	/* ssd1326 */
u8x8_d_ssd1327.c:  /* write_pulse_width_ns = */ 60,	
u8x8_d_ssd1327.c:  /* write_pulse_width_ns = */ 60,	
u8x8_d_ssd1329.c:  /* write_pulse_width_ns = */ 60,	/* ssd1329 */
u8x8_d_ssd1606_172x72.c:  /* write_pulse_width_ns = */ 150,	
u8x8_d_ssd1607_200x200.c:  /* write_pulse_width_ns = */ 150,	
u8x8_d_st75256.c:  /* write_pulse_width_ns = */ 70,	
u8x8_d_st75256.c:  /* write_pulse_width_ns = */ 70,	
u8x8_d_st75256.c:  /* write_pulse_width_ns = */ 70,	
u8x8_d_st7565.c:  /* write_pulse_width_ns = */ 80,	/* st7565 datasheet, table 24, tcclw */
u8x8_d_st7565.c:  /* write_pulse_width_ns = */ 80,	/* st7565 datasheet, table 24, tcclw */
u8x8_d_st7565.c:  /* write_pulse_width_ns = */ 80,	/* st7565 datasheet, table 24, tcclw */
u8x8_d_st7565.c:  /* write_pulse_width_ns = */ 80,	/* st7565 datasheet, table 24, tcclw */
u8x8_d_st7565.c:  /* write_pulse_width_ns = */ 80,	/* st7565 datasheet, table 24, tcclw */
u8x8_d_st7565.c:  /* write_pulse_width_ns = */ 80,	/* st7565 datasheet, table 24, tcclw */
u8x8_d_st7565.c:  /* write_pulse_width_ns = */ 80,	/* st7565 datasheet, table 24, tcclw */
u8x8_d_st7567.c:  /* write_pulse_width_ns = */ 80,	/* */
u8x8_d_st7567.c:  /* write_pulse_width_ns = */ 80,	/* */
u8x8_d_st7588.c:  /* write_pulse_width_ns = */ 50,	
u8x8_d_st7920.c:  /* write_pulse_width_ns = */ 40,
u8x8_d_st7920.c:  /* write_pulse_width_ns = */ 40,
u8x8_d_t6963.c:  /* write_pulse_width_ns = */ 80,
u8x8_d_t6963.c:  /* write_pulse_width_ns = */ 80,
u8x8_d_t6963.c:  /* write_pulse_width_ns = */ 80,
u8x8_d_t6963.c:  /* write_pulse_width_ns = */ 80,
u8x8_d_uc1601.c:  /* write_pulse_width_ns = */ 80,	/* uc1601 datasheet, page 43 */
u8x8_d_uc1604.c:  /* write_pulse_width_ns = */ 35,	
u8x8_d_uc1608.c:  /* write_pulse_width_ns = */ 35,	/* uc1608 datasheet, page 39 */
u8x8_d_uc1608.c:  /* write_pulse_width_ns = */ 35,	/* uc1608 datasheet, page 39 */
u8x8_d_uc1608.c:  /* write_pulse_width_ns = */ 35,	/* uc1608 datasheet, page 39 */
u8x8_d_uc1610.c:  /* write_pulse_width_ns = */ 40,
u8x8_d_uc1611.c:  /* write_pulse_width_ns = */ 80,	/* uc1611 datasheet, page 60 */
u8x8_d_uc1611.c:  /* write_pulse_width_ns = */ 80,	/* uc1611 datasheet, page 60 */
u8x8_d_uc1611.c:  /* write_pulse_width_ns = */ 80,	/* uc1611 datasheet, page 60 */
u8x8_d_uc1617.c:  /* write_pulse_width_ns = */ 65,	/* uc1617 datasheet, page 52 */
u8x8_d_uc1638.c:  /* write_pulse_width_ns = */ 35,	/*  */
u8x8_d_uc1701_dogs102.c:  /* write_pulse_width_ns = */ 40,
u8x8_d_uc1701_mini12864.c:  /* write_pulse_width_ns = */ 40,

@olikraus
Copy link
Owner

one more question: Will a delay of 512ns be sufficient?

@roberto314
Copy link
Author

I thought ONLY change the KS0108 driver to 2*10NANO and leave the others alone.
A delay of 512ns won't be sufficent as i need 2.8us!

@olikraus
Copy link
Owner

olikraus commented Jan 28, 2018

I thought ONLY change the KS0108 driver to 2*10NANO and leave the others alone.
A delay of 512ns won't be sufficent as i need 2.8us!

But how? The value for the delay is stored in a data structure which is common to all displays.
This structure (u8x8_display_info_t) has a 8 bit value for the nano-delay. So, 255ns is max for all displays.

If I change the meaning of the 8bit, I have top update all displays (see list above).
If I extend this to 16 bit i have many more things to change.

The question is, what is how can I introduce larger delay without affecting other displays, without increasing the size of the code and data.

@olikraus
Copy link
Owner

olikraus commented Jan 28, 2018

currently I think about a none-linear function like this:

#include <stdio.h>
#include <stdint.h>

uint16_t fn(uint8_t x)
{
    if ( (x & 128) == 0  )
      return x;
    return 128 + ((x&127)<<5);
      
}

void main(void)
{
  uint16_t i;
  uint16_t r;
  for( i = 0; i < 256; i+=10 )
  {
    r = fn(i);
    printf("%d --> %d\n", (int)i, (int)r);
  }
}

result is:

0 --> 0
10 --> 10
20 --> 20
30 --> 30
40 --> 40
50 --> 50
60 --> 60
70 --> 70
80 --> 80
90 --> 90
100 --> 100
110 --> 110
120 --> 120
130 --> 192
140 --> 512
150 --> 832
160 --> 1152
170 --> 1472
180 --> 1792
190 --> 2112
200 --> 2432
210 --> 2752
220 --> 3072
230 --> 3392
240 --> 3712
250 --> 4032

You probably want to put 212, which will result a delay of 2816 = 128+ (212-128) x 32 = 128+84 x 32

@olikraus
Copy link
Owner

I could add a scaling function (inverse function of the above):

#define RFN(x) (((x)<128)?(x):((((x)-128+31) >> 5)+128))

So for 2800ns you just write RFN(2800) and the result will be 212

@olikraus
Copy link
Owner

One more thing: 450ns is the official value. I will include this value into the lib. So I guess you need to patch u8g2 for your specific display anyway.

@roberto314
Copy link
Author

That sounds like a plan. So you discarded the idea of 10_NANO instead of 1_NANO delay functions? The implementations will have to change anyway (because 150ns of the ssd1309 is no longer 150ns but 832ns). IMO it would make sense to do both.

@olikraus
Copy link
Owner

oh, i just realized, that i have an extra function for ks0108:
uint8_t u8x8_byte_ks0108(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
I can two calls (double the range):
https://github.com/olikraus/u8g2/blob/master/csrc/u8x8_byte.c#L344

Then 450ns would have the value 225 in the config struct

@olikraus
Copy link
Owner

So you discarded the idea of 10_NANO instead of 1_NANO delay functions?

Well, yes, almost. The problem is, changing this will break all existing HAL implementations for u8g2.

The implementations will have to change anyway (because 150ns of the ssd1309 is no longer 150ns but 832ns). IMO it would make sense to do both.

ok, I do not understand the SSD1309 remark, but yes, all calls dispalys have to be changed. But it would be more like adding a macro around the existing values.

Nevertheless, I think I prefer a specific solution for the KS0108.

@roberto314
Copy link
Author

I meant the function which implements the actual delay has to be changed. It would only work as before for values below 128.

@olikraus
Copy link
Owner

I would probably change only the meaning of the delay field...

@roberto314
Copy link
Author

But in the delay implementation the meaning would be interpreted wrong!
For example: Let's stay with the SSD1309 implementation, we need 150ns so, to use your macro RFN(150) which equals to something like 129 (i haven't calculated it, just a guess). Th NANO Delay function gets 129 and interprets it as 129ns NOT 128+ (129-128) x 32 = 128+32 = 160ns which would likely cause the display to malfunction.
I don't know, maybe i am wrong in general, but in my specific application that would be a problem.

@olikraus
Copy link
Owner

The meaning of the delay field would be changed only for the ks0108. So other devices are not touched.

@roberto314
Copy link
Author

roberto314 commented Jan 30, 2018 via email

olikraus added a commit that referenced this issue Feb 13, 2018
@olikraus
Copy link
Owner

ok, not a perfect solution, but at least it fixed the problem (hopefully)

@olikraus
Copy link
Owner

closing for now...

@olikraus olikraus added this to the 2.21 milestone Feb 13, 2018
@olikraus olikraus added the bug label Feb 13, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants