Sonsivri
 
*
Welcome, Guest. Please login or register.
Did you miss your activation email?
November 25, 2024, 03:51:51 15:51


Login with username, password and session length


Pages: [1]
Print
Author Topic: ST7920 driver  (Read 8403 times)
0 Members and 1 Guest are viewing this topic.
mpavlica
Newbie
*
Offline Offline

Posts: 25

Thank You
-Given: 32
-Receive: 3


« on: July 31, 2014, 10:36:16 10:36 »

Hi
This is driver that I am currently using:
Coded with mikroC v6

Soon to come - RA8875 driver
« Last Edit: July 31, 2014, 11:18:21 11:18 by mpavlica » Logged
metal
Global Moderator
Hero Member
*****
Offline Offline

Posts: 2420

Thank You
-Given: 862
-Receive: 678


Top Topic Starter


« Reply #1 on: July 31, 2014, 02:30:21 14:30 »

Look at this though: http://www.youtube.com/watch?v=EaO9-2IXoUs watch it till the end.
Logged
mpavlica
Newbie
*
Offline Offline

Posts: 25

Thank You
-Given: 32
-Receive: 3


« Reply #2 on: July 31, 2014, 05:14:04 17:14 »

I know, it is slow, but its cheap, and it works perfect for what I need it for...
Also i am working on RA8875 library, it should be finished in a few days...
Logged
metal
Global Moderator
Hero Member
*****
Offline Offline

Posts: 2420

Thank You
-Given: 862
-Receive: 678


Top Topic Starter


« Reply #3 on: August 01, 2014, 01:02:40 01:02 »

is it a faster controller, or there are still faster ones out there?
Logged
Old_but_Alive
Senior Member
****
Offline Offline

Posts: 331

Thank You
-Given: 745
-Receive: 120


« Reply #4 on: August 01, 2014, 05:59:26 05:59 »

I have been looking for an SD1306 driver for PIC's for a long time.
preferably CCS "C" but mikroC would be OK.


I tried to modify adafruit ardinuo code, but only partially succeeded.

The main problem as I see it is the lack of RAM in PIC's, since most of the SD1306 drivers use a RAM buffer, so 1KB of RAM is required just for the graphics buffer.

any thoughts or help ?
Logged

I fought Ohm's Law ...  and the law won
I only use Mosfets because I have a Bipolar mental disorder :-)
mpavlica
Newbie
*
Offline Offline

Posts: 25

Thank You
-Given: 32
-Receive: 3


« Reply #5 on: August 01, 2014, 09:23:42 09:23 »

With every LCD i am using a small trick - any text message that you write is kept in RAM, thats why RAM is used up quickly. I am storing them as const array in ROM and then I copy them in RAM when i want to use it.


char msg[17]; //declare array set to max size required plus 1 [for terminator] for copying into

// copy const to ram string
char * CopyConst2Ram(char * dest, const char * src){
  char * d ;
  d = dest;
  for(;*dest++ = *src++;)
    ;
  return d;
}



const char LCD_txt1[] = "TEST";

Lcd_Out(1,1,CopyConst2Ram(msg,LCD_txt1)); // Write text in first row

This is what I am using, and what i found on

http://www.mikroe.com/forum/viewtopic.php?f=88&t=51613
Check there for more details...
Logged
zuisti
Senior Member
****
Offline Offline

Posts: 409

Thank You
-Given: 242
-Receive: 780


« Reply #6 on: August 01, 2014, 10:45:05 10:45 »

With every LCD i am using a small trick - any text message that you write is kept in RAM, thats why RAM is used up quickly. I am storing them as const array in ROM and then I copy them in RAM when i want to use it.

An other (quicker) solution, without copying, no any RAM buffer, written by me (IstvanK) on the above mikroE site:

Lcd_COut: positioned print, the string is placed in the code memory (a little tricky)

Code:
 void Lcd_COut(char row, char col, const char *cptr) {
  char chr = 0;             //first, it is used as empty string
  Lcd_Out(row, col, &chr);  //nothing to write but set position.
  for ( ; chr = *cptr ; ++cptr ) Lcd_Chr_CP(chr); //out in a loop
}

//examples:
  Lcd_COut(1, 4, "A constant string");
     //or
  const char demo[] = "This is also constant";
  Lcd_COut(2, 2, demo);

Logged
gan_canny
Junior Member
**
Offline Offline

Posts: 89

Thank You
-Given: 101
-Receive: 26


« Reply #7 on: August 01, 2014, 02:25:17 14:25 »

I have written drivers for CCS compilers EX SSD1289....Most controllers and I glanced at the sd1306 data sheet have an on board ram that supports a full screen of pixels. In the CCS code fonts are stored in ROM ( program memory space) with a 24 pic this is many kilobytes ( ex 256k). Using the CCS printf to a function and global variables with the xy screen position the results of a printf are transferred via the special CCS function call char by char to a routine that sets and clears the controllers graphic ram pixels at the xy location after fetching the chars font from PIC ROM. Graphics are done via Breshenham algorithms.
Variations between controllers are mostly in the initialization routine and with the physical interface (I2C SPI parallel etc.)
Logged
Old_but_Alive
Senior Member
****
Offline Offline

Posts: 331

Thank You
-Given: 745
-Receive: 120


« Reply #8 on: August 02, 2014, 06:15:39 06:15 »

there is no " set xy" commands in the SD1306.

and whilst there is ram in the sd1306, its only there for internal display refresh.

Also, using the I2C interface, one cannot read pixel data, so there is no way to "unset" a pixel value.

It is arranged  as "pages", so with a 128x64 display, there are 8 pages, 8 bits deep, and 128 long, so you have to write 8 bits at a time.

try drawing a line or circle !!!

Thus one must have the ram buffer, manipulate  the ram buffer with "pixel" commands, then write it all to the SD1306 afterwards.

I got as far as being able to write text with one font, but with CCS's lack of pointers and ansi standard, it fell apart
« Last Edit: August 02, 2014, 06:19:12 06:19 by Old_but_Alive » Logged

I fought Ohm's Law ...  and the law won
I only use Mosfets because I have a Bipolar mental disorder :-)
gan_canny
Junior Member
**
Offline Offline

Posts: 89

Thank You
-Given: 101
-Receive: 26


« Reply #9 on: August 02, 2014, 02:25:21 14:25 »

Most often for text either a single char or a line is written...the css code contains the chars  to write in ascii so there is no need to read the graphic controller ram ..text is just overwritten.
Now the 8 bit write for graphics often isn't a problem for the ccs code encapsulates the graphics as function calls for  boxes lines circles ( filled unfilled pensize). Setting or unsetting or setting a single pixel is done by rewriting the 8bits of the graphic controller memory containing the pixel. The graphic ccs routine requires a small coordinate conversion from xy pixels to XY.b graphic controller XYbyte and bit.
As far as fonts go in a pic 24 ROM space I often have several fonts and in ccs code I can scale them. I'm not a fan of pointers except for linked lists. The PIC rom is addressable
 via pointers or as I prefer for fonts just the array reference indexed in order by ascii value with the origin set in the case below to the space char ascii value.
#ifdef Font08x08
unsigned int8 const CFONT08x08[] = {
 // unsigned int8 const CFONT08x08[784] = {
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // space 0x20
0x30,0x78,0x78,0x30,0x30,0x00,0x30,0x00, // !
0x6C,0x6C,0x6C,0x00,0x00,0x00,0x00,0x00, // "
The ccs compiler needs a heads up as to how strings are passed
#include <24FJ256GA110.h>
#device PASS_STRINGS = IN_RAM   //// required to support pointers to constants like"a"
Logged
Old_but_Alive
Senior Member
****
Offline Offline

Posts: 331

Thank You
-Given: 745
-Receive: 120


« Reply #10 on: August 02, 2014, 05:26:10 17:26 »

nobody seems to have understood the request.

All replies have been about text driving
Logged

I fought Ohm's Law ...  and the law won
I only use Mosfets because I have a Bipolar mental disorder :-)
metal
Global Moderator
Hero Member
*****
Offline Offline

Posts: 2420

Thank You
-Given: 862
-Receive: 678


Top Topic Starter


« Reply #11 on: August 03, 2014, 01:48:49 01:48 »

An other (quicker) solution, without copying, no any RAM buffer, written by me (IstvanK) on the above mikroE site:

Lcd_COut: positioned print, the string is placed in the code memory (a little tricky)

Code:
 void Lcd_COut(char row, char col, const char *cptr) {
  char chr = 0;             //first, it is used as empty string
  Lcd_Out(row, col, &chr);  //nothing to write but set position.
  for ( ; chr = *cptr ; ++cptr ) Lcd_Chr_CP(chr); //out in a loop
}

//examples:
  Lcd_COut(1, 4, "A constant string");
     //or
  const char demo[] = "This is also constant";
  Lcd_COut(2, 2, demo);

nice one zuisti:
Code:
for ( ; chr = *cptr ; ++cptr ) Lcd_Chr_CP(chr);
the dereferenced pointer cptr is assigned to chr so that chr value is to be displayed but once cptr is equal to 0, the for loop will see the condition as 0 as chr holds 0 and exits the loop and 0 never gets printed out, very clever indeed. I rarely see this trick by people writing C.

I attached a small windows executable test to demonstrate the idea.

source on mE forum
Logged
Ichan
Hero Member
*****
Offline Offline

Posts: 833

Thank You
-Given: 312
-Receive: 392



WWW
« Reply #12 on: August 03, 2014, 11:44:42 11:44 »

Code:
for ( ; chr = *cptr ; ++cptr ) Lcd_Chr_CP(chr);

That code assumes that the string always null terminated, code below should work too:

Code:
while(*cptr) Lcd_Chr_CP(*++cptr);

A bit out off topic, just about ten years ago i got a related lifetime lesson from a great person on HTSOFT forum, may people can learn something too, here is the link: Printing Floats.

I wonder if the person actually in here too, then my greet to him.

To be back on topic, my little suggestion to the OP on the driver code is to add a time out mechanism when querying the LCD status.


-ichan
Logged

There is Gray, not only Black or White.
pickit2
Moderator
Hero Member
*****
Offline Offline

Posts: 4668

Thank You
-Given: 834
-Receive: 4322


There is no evidence that I muted SoNsIvRi


« Reply #13 on: August 03, 2014, 01:27:26 13:27 »

do you mean john payson, if so he is not here.
http://ericlippert.com/2014/05/01/lowering-in-language-design-part-two/
Logged

Note: I stoped Muteing bad members OK I now put thier account in sleep mode
metal
Global Moderator
Hero Member
*****
Offline Offline

Posts: 2420

Thank You
-Given: 862
-Receive: 678


Top Topic Starter


« Reply #14 on: August 04, 2014, 12:52:39 00:52 »

That code assumes that the string always null terminated, code below should work too:

Code:
while(*cptr) Lcd_Chr_CP(*++cptr);

-ichan

I have this in my LCD driver Ichan:

Code:
/* write a string of chars to the LCD */

void
lcd_puts(const char * s)
{
LCD_RS = 1; // write characters

while(*s) lcd_write(*s++);
}

same principle, one uses for, the other familiar form uses the while. I see while used for this task more than for as it seems to be more readable.
Logged
zuisti
Senior Member
****
Offline Offline

Posts: 409

Thank You
-Given: 242
-Receive: 780


« Reply #15 on: August 04, 2014, 10:29:09 10:29 »

These C discussions are a bit off-topic here (sorry mods). However, let me to write some things yet:

while (*cptr)  Lcd_Chr_CP(*cptr++);    // and NOT *++cptr (@ichan !!)
for ( ; *cptr ; Lcd_Chr_CP(*cptr++) );

- The above C lines result an absolutely same asm code since both are simple 'front tested' loops.

But:
- dereference of a pointer to const chars is much more code consuming (especially on a PIC12/16, see the .asm or .lst output files), so I always try to avoid the double use, using a temporarily (local) variable to hold the dereferenced value.

- and try to avoid this form too:
...........*ptr++; // we get a larger code in most case.
 instead, use two instructions:
...........*ptr; ptr++;

I'm using this solution:
for ( ; chr = *cptr ; ++cptr ) Lcd_Chr_CP(chr);

but - if you want - use the while syntax:
while ( chr = *cptr)
 { Lcd_Chr_CP(chr); ++cptr; }


This method is well-known, the trick in my Lcd_COut function (see my previous post) does not only this.
The other trick is the (otherwise necessary) temporary variable is using as an empty string for positioning:

void Lcd_COut(char row, char col, const char *cptr) {
  char chr = 0;                  //first, it is used as empty string
  Lcd_Out(row, col, &chr);  //nothing to write but set position.
  for ( ; chr = *cptr ; ++cptr ) Lcd_Chr_CP(chr); //out in a loop
}

And yes, I am 'IstvanK' on the mikroE forum, and 'Istvan K' on LibStock (abbreviation of my real name).
zuisti
« Last Edit: August 04, 2014, 11:33:18 11:33 by zuisti » Logged
metal
Global Moderator
Hero Member
*****
Offline Offline

Posts: 2420

Thank You
-Given: 862
-Receive: 678


Top Topic Starter


« Reply #16 on: August 04, 2014, 01:10:20 13:10 »

No problem, if the off-topic discussion gets larger, I will move it to a new thread.

I did not pay attention to the prefix increment either, it must be a post one or a character will be lost  Huh
TBH, I did not know that mixing the dereferencing and pre/postfix inc/dec operators will consume more code.

This hint reminds me that using multiple if else statements instead of a single switch statement will consumes less code as well.

Logged
zuisti
Senior Member
****
Offline Offline

Posts: 409

Thank You
-Given: 242
-Receive: 780


« Reply #17 on: August 04, 2014, 03:52:23 15:52 »

... mixing the dereferencing and pre/postfix inc/dec operators will consume more code.
Only the double used dereferencing (no any temp var) and/or the dereferencing with postinc/postdec (eg *ptr++) will consume more code.
To show how works the (most) compiler:

- first temporarily stores the value of the ptr
- then increments it (the ptr)
- then retrieves the previous, stored value
- and this is used for dereferencing

---- nice, is not it?

Quote
This hint reminds me that using multiple if else statements instead of a single switch statement will consumes less code as well.
Yes, but the switch is always clearer (more understandable). And if you have enough RAM and ROM (like on a PC  Wink or a very big uC, eg an ARM) then you can feel free to use the more concise syntax like the switch-case method, or the above (more elegant) postinc-ed dereferencing, all will work well. But the usual embedded world is an other thing, here we have much smaller RAM and ROM so the efficient programming is a must.

The switch-case is elegant and clear, but the if/else may be often more effective. Here is a frequently occurring example:
Code:
//using switch:
switch (sw) {
 case 0:
   ....
   break;
 case 1:
   ....
   break;
 case 2:
   ....
   break;
//and so on ...
}

//using multiple IFs it is much smaller and faster (in this special case):
if (!sw) {         // was 0 (zero)
 ........
}
else if (!--sw) { //was 1
 .......
}
else if (!--sw) { //was 2
 .......
}
//and so on ...
 
Logged
Ichan
Hero Member
*****
Offline Offline

Posts: 833

Thank You
-Given: 312
-Receive: 392



WWW
« Reply #18 on: August 08, 2014, 07:28:40 07:28 »

do you mean john payson, if so he is not here.

Yes he is, i certainly will invite him if he apply for it. Here is a snip and a link from piclist website:

Binary to BCD unpacked 16 bit to 5 digit - Here's a routine written by John Payson that is optimized to convert a 16-bit binary number into 5 BCD digits. Like most of the John writes, this is bizarre, interesting, and extremely fast.



while (*cptr)  Lcd_Chr_CP(*cptr++);    // and NOT *++cptr (@ichan !!)

Yup, you are right  Cheesy.


-ichan
Logged

There is Gray, not only Black or White.
Pages: [1]
Print
Jump to:  


DISCLAIMER
WE DONT HOST ANY ILLEGAL FILES ON THE SERVER
USE CONTACT US TO REPORT ILLEGAL FILES
ADMINISTRATORS CANNOT BE HELD RESPONSIBLE FOR USERS POSTS AND LINKS

... Copyright © 2003-2999 Sonsivri.to ...
Powered by SMF 1.1.18 | SMF © 2006-2009, Simple Machines LLC | HarzeM Dilber MC