CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

Pointers...... and LCD driver

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
curt2go



Joined: 21 Nov 2003
Posts: 200

View user's profile Send private message

Pointers...... and LCD driver
PostPosted: Thu Jul 16, 2020 5:42 pm     Reply with quote

I am attempting to clean up some rotten code for a few years ago. I had originally used a function for each font type to draw the letters on the screen.

I am not trying to make a "generic driver" that will take a pointer to the chars and also let me know where to start of the font array I would like to use this time.

The font array is built with a const unsigned int8 array.

An example of how it works:
Code:
const unsigned int8 timesNewRoman[] {

0x00,0x00..................

};

const unsigned int8 anotherFont[] {

0x00,0x00..................

};

sprintf(someCharArray,"Hello World");
buildTheLCD(someCharArray,timesNewRoman);



void buildTheLCD(char *inChar, unsigned int8 *fontInt){

}

I am building the font arrays with the same structure, first 2 bytes will be height and width, then each char row will be the same length after that. I am looking at using pointers because I want to pass the different locations of the different fonts into the function. This will make it so I don't have to use different functions that just use the different font arrays directly.

I am having trouble with moving the pointer to the appropriate char start location in the font array. So lets say I want to display the char '!' , so the start of the timesNewRoman array is location [74] . Each char is made of [72] bytes. My pointer math is no good so i thought I would ask. But maybe it's just cause it can't be done this way.

I will also point out I am using the 24EP256GU206 chip and 5.083 compiler. I am trying to save space by using the const for the font arrays. I have a few fonts and they can get pretty large.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Jul 16, 2020 6:41 pm     Reply with quote

It worked for me. I made a test program with CCS vs.5.094 and ran it.
It displayed 0x12, just like it should. The output window of the MPLAB 8.92
simulator shows this result:
Quote:
12

Test program:
Code:

#include <18F46K22.h>
#device PASS_STRINGS=IN_RAM
#fuses NOWDT 
#use delay(internal=4M)
#use rs232(UART1, baud=9600, ERRORS)

void buildTheLCD(char *ptr)
{
printf("%x \r", *ptr);
}

//--------------------------------
const unsigned int8 timesNewRoman[] = {0x12, 0x34};

const unsigned int8 anotherFont[] = {0x56, 0x78};

//=================================
void main()
{
buildTheLCD(timesNewRoman);

while(TRUE);
}
curt2go



Joined: 21 Nov 2003
Posts: 200

View user's profile Send private message

PostPosted: Thu Jul 16, 2020 6:56 pm     Reply with quote

Yes, i do agree. I can get the first line of chars as well. But after that , things go haywire.

Each char has 72 bytes, chars are from 32 to 128. At least for the first font that I am rebuilding. The bytes per char will obviously vary based on a few things.

Or even let's say I want to start the pointer at timerNewRoman[0] + 346; that's what is not working properly.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Jul 16, 2020 7:09 pm     Reply with quote

In that case I think you have to use rom pointers. Declare the data as 'rom'
not 'const'.
curt2go



Joined: 21 Nov 2003
Posts: 200

View user's profile Send private message

PostPosted: Thu Jul 16, 2020 7:26 pm     Reply with quote

I did try that as well. Unless I am doing something really dumb, which probably is the case. I will give it another shot.


Gave it another shot. Found that I was not using the rom in the function as well.

Why does it not work with const? Its weird.
curt2go



Joined: 21 Nov 2003
Posts: 200

View user's profile Send private message

PostPosted: Thu Jul 16, 2020 8:04 pm     Reply with quote

It also takes a very long time , instruction wise to run it in ROM. like 20 times longer.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Jul 16, 2020 10:19 pm     Reply with quote

Quote:
Why does it not work with const? Its weird.

Const data has overhead bytes at the start of the data.


I made two test programs. Printf ran slow, so I changed it to putc() in
each case. I ran both in MPLAB vs. 8.92 simulator with the simulator
frequency set to 4 MHz to match the #use delay() statement in each case.
I put a breakpoint on the while(TRUE) statement in each program.
Then I clicked on the "Run" arrow toolbar button in MPLAB.

The 'const' program ran in 55 usec, and the 'rom' program ran in 73 usec.

const program:
Code:
#include <18F46K22.h>
#device PASS_STRINGS=IN_RAM
#fuses NOWDT 
#use delay(internal=4M)
#use rs232(UART1, baud=9600, ERRORS)

void buildTheLCD(char *ptr)
{
putc(*ptr);
}

//--------------------------------
const unsigned int8 timesNewRoman[] = {0x41, 0x42};

//const unsigned int8 anotherFont[] = {0x56, 0x78};

//=================================
void main()
{
buildTheLCD(timesNewRoman);  // Will display the letter 'A' (0x41)

while(TRUE);
}

rom program:
Code:
#include <18F46K22.h>
#use delay(internal=4M)
#use rs232(baud=9600, UART1, ERRORS)

void buildTheLCD(rom *ptr)
{
putc(*ptr);
}

//--------------------------------
rom unsigned int8 timesNewRoman[] = {0x41, 0x42, 0x43, 0x44, 0x45, 0x46};


//=====================
void main()
{
buildTheLCD(timesNewRoman + 4);  // Will display the letter 'E' (0x45)
   
while(TRUE);
}
Ttelmah



Joined: 11 Mar 2010
Posts: 19515

View user's profile Send private message

PostPosted: Fri Jul 17, 2020 1:29 am     Reply with quote

The key thing here really is TANSTAAFL.....

If you access a variable at a fixed location in RAM, the code can read it in a
single instruction. Do it via a 'pointer', and suddenly perhaps a dozen
instructions are needed for the same access. Even worse, put it in ROM,
and the instructions needed for access 'shoot up' (the PIC is one of the
very few processors where the ROM and RAM are in separate memory
spaces, and there is a relatively high overhead involved in reading a byte
from the program memory...).
PCM is showing you how to do this with rom pointers (note the rom *),
and this can be made to work well, but it does come at a cost in performance.
That the pointers have to change is because of the two memories being
in difference spaces. So there is an 'address 0' in ROM, and a second
'address 0' in RAM. The code has to be told to switch to the second memory
space. The exceptions to this on the PIC are:
1) String arrays stored in ROM. The option 'PASS_STRINGS=IN_RAM',
allows the compiler to automatically 'virtualise' such ROM access into
RAM, using a small buffer. If your font declarations could be changed to
character arrays, this could be used.
2) PIC24/30/33's where the option 'PSV' can be used, to create a
'window' space between the ROM and the RAM. Downside is is costs
storage space (only stores 2 bytes per instruction in this mode). However
a powerful feature of these more complex chips....

So having a pointer based ROM font array is going to cost performance.
You will have to make the decision whether this is acceptable.
curt2go



Joined: 21 Nov 2003
Posts: 200

View user's profile Send private message

PostPosted: Fri Jul 17, 2020 7:29 am     Reply with quote

You guys are awesome. I have been working with PICs for over 20 years now and still don't know a fraction of you guys. Thank you and keep up the good work.

I am going to look into the 'PSV' mode.

Because this is a 480x320 lcd driver, each char is a lot of pixels, so speed is a big issue.

*** edit****

Code:
void buildTheLCD(char *ptr)
{
putc(*ptr);
}

//--------------------------------
const unsigned int8 timesNewRoman[] = {0x41, 0x42};

//const unsigned int8 anotherFont[] = {0x56, 0x78};

//=================================
void main()
{
buildTheLCD(timesNewRoman);  // Will display the letter 'A' (0x41)

while(TRUE);
}

In this scenario, I increment through timesNewRoman in the buildTheLCD(char *ptr) function. That was where I was getting hung up with longer arrays. It seemed as though the pointer would only increment to around 48.

I originally was trying to pass the buildTheLCD function the location of the timesNewRoman start, so then I could just increment through it to find the bytes i needed in the timesNewRoman array.
temtronic



Joined: 01 Jul 2010
Posts: 9228
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Fri Jul 17, 2020 5:37 pm     Reply with quote

Silly comment
you've got an array of 96 characters, each needing 72 bytes which is an array 6912 bytes long
..so to get to the 'bit pattern' of the 4th character, you'd be 4 * 72 or 288 bytes offset from the start ?
Shouldn't you be using unsigned int16 for the 'position' or actual 'element' to access the bit pattern data ? 'char' is 0-255.
Maybe I'm looking at this all wrong, it's hot up here, I'm 67 and win7 taskbar 'magically' changed the colour of the taskbar....grrrrrrr
curt2go



Joined: 21 Nov 2003
Posts: 200

View user's profile Send private message

PostPosted: Wed Jul 22, 2020 6:01 pm     Reply with quote

Yes for sure an INT16 is needed.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group