|
|
View previous topic :: View next topic |
Author |
Message |
nickdc
Joined: 19 Sep 2018 Posts: 15
|
Problems with ROM and LCD font |
Posted: Mon Jun 29, 2020 2:56 am |
|
|
I have a problem with printing certain characters to my LCD, after I added a symbol to my font set.
I use CCS compiler 5.078, PIC18F57K42, I use opt compress because else it doesn't fit into memory. The compiler optimization level of the project is in the properties set to 9.
I use a bootloader from Brush Electronics Software. Loading an image works fine.
I have had this problem before, and I solved it with a trick using trial and error. But I would like to know if there is a more structural way to deal with this sort of issues. I think the bootloader interaction adds to the complexity of the problem. Maybe people here could give some pointers into how to deal with this sort of problem? I also don't understand what really is the source of the problem regarding the ROM, i.e. why my code breaks. Maybe it's because the array uses a too large contiguous memory space. But why does it work when I handle some symbols separately (see my code, I mean symbols like ç and ê)?
Maybe it's better to contact Brush Electronics directly with this issue?
I already splitted my font in these two arrays (pseudocode):
Code: |
const unsigned int8 FONT[51][5] ={0x00, 0x00, 0x00, 0x00, 0x00, // SPACE
// 51 lines
...
// Table going from line 53 to 96
const unsigned int8 FONT2[44][5]={0x26, 0x49, 0x49, 0x49, 0x32, // S |
In my main I have handled certain characters separately that didn't work with using these two tables. Now I have included handling the symbol °, like I did with the other symbols, and the code breaks again.
Code: | const unsigned int8 FAULTY_CHARS [4][5]= {
0x3E, 0x49, 0x49, 0x49, 0x32, // 6
0x01, 0x01, 0x71, 0x09, 0x07, // 7
0x36, 0x49, 0x49, 0x49, 0x36, // 8
0x26, 0x49, 0x49, 0x49, 0x3E // 9
};
const unsigned int8 CEDILLA [1][5] = {
0x18, 0xA4, 0xE4, 0x24, 0x08 // ç
};
const unsigned int8 LOW_E_ACUTE [1][5] = {
0x38, 0x56, 0x55, 0x54, 0x58 // 154 é
};
const unsigned int8 LOW_E_CIRCUMFLEX [1][5] = {
0x38, 0x56, 0x55, 0x56, 0x58 // 155 ê
};
const unsigned int8 LOW_A_DIAERESIS [1][5] = {
0x20, 0x55, 0x54, 0x79, 0x40 // ä
};
const unsigned int8 LOW_U_DIAERESIS [1][5] = {
0x3C, 0x41, 0x40, 0x21, 0x7C // ü
};
const unsigned int8 LOW_O_DIAERESIS [1][5] = {
0x38, 0x45, 0x44, 0x45, 0x38 // ö
};
const unsigned int8 DEGREE_SIGN [1][5] = {
0x00, 0x07 , 0x05 , 0x07 , 0x00 // °
};
|
This is the method that I use to print characters. The change I made here was also adding the code for DEGREE_SIGN.
Code: | #separate
void glcd_text57(unsigned int8 x, unsigned int8 y, char* textptr, unsigned int8 size, int1 color) {
unsigned int8 j, k, l, m; // Loop counters
unsigned int8 pixelData[5]; // Stores character data
for (; *textptr != '\0'; ++textptr, ++x)// Loop through the passed string
{
if (*textptr < 'S'){ // Checks if the letter is in the first font array
if (*textptr == '6'){
memcpy(pixelData, FAULTY_CHARS[0], 5);
}
else if(*textptr == '7'){
memcpy(pixelData, FAULTY_CHARS[1], 5);
}
else if(*textptr == '8'){
memcpy(pixelData, FAULTY_CHARS[2], 5);
}
else if(*textptr == '9'){
memcpy(pixelData, FAULTY_CHARS[3], 5);
}
else {
memcpy(pixelData, FONT[*textptr - ' '], 5);
}
}
else if (*textptr <= '~'){ // Check if the letter is in the second font array
memcpy(pixelData, FONT2[*textptr - 'S'], 5);
}
else if (*textptr == 'ç'){
memcpy(pixelData, CEDILLA[0], 5);
}
else if (*textptr == 'é'){
memcpy(pixelData, LOW_E_ACUTE[0], 5);
}
else if (*textptr == 'ê'){
memcpy(pixelData, LOW_E_CIRCUMFLEX[0], 5);
}
else if (*textptr == 'ä'){
memcpy(pixelData, LOW_A_DIAERESIS[0], 5);
}
else if (*textptr == 'ü'){
memcpy(pixelData, LOW_U_DIAERESIS[0], 5);
}
else if (*textptr == 'ö'){
memcpy(pixelData, LOW_O_DIAERESIS[0], 5);
}
else if (*textptr == '°'){
memcpy(pixelData, DEGREE_SIGN[0], 5);
}
else
memcpy(pixelData, FONT[0], 5); // Default to space
// Handles newline and carriage returns
switch (*textptr) {
case '\n':
y += 7 * size + 1;
continue;
case '\r':
x = 0;
continue;
}
if (x + 5 * size >= GLCD_WIDTH) // Performs character wrapping
{
x = 0; // Set x at far left position
y += 7 * size + 1; // Set y at next position down
}
for (j = 0; j < 5; ++j, x += size) // Loop through character byte data
{
for (k = 0; k < 7; ++k) // Loop through the vertical pixels
{
if (bit_test(pixelData[j], k)) // Check if the pixel should be set
{
for (l = 0; l < size; ++l) // These two loops change the
{ // character's size
for (m = 0; m < size; ++m) {
glcd_pixel(x + m, y + k * size + l, color); // Draws the pixel
}
}
}
}
}
}
} |
Now I have problems with certain characters that aren't displayed correctly.
One specific problem is that the character '1' shows as '$'.
2 is some blob. 3 is a ';'. 4 is also blobs. The issue seems to be with numerical characters.
0 is OK
5 to 9 is OK
All capital letters are OK.
Why do numerical characters seem to be affected most?
If extra information is needed to solve this problem, please feel free to ask.
Last edited by nickdc on Mon Jun 29, 2020 3:31 am; edited 2 times in total |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19538
|
|
Posted: Mon Jun 29, 2020 3:26 am |
|
|
Your problem is trying to use memcpy....
A const, array by default, does not have the array name being a 'pointer'
to memory that can be used by memcpy. memcpy, is designed to handle
RAM moves. The command to get the physical 'address' of a const is
'label_address'.
Now this is becoming important here, because when you use 'compress', the
actual table of data stored in the ROM is no longer a continuous 'lump' that
can be copied with memcpy. What the compiler does is remove characters
that don't need to be there in the ROM.
The data would be read correctly, if you copied it 'manually':
Code: |
int count;
for (count=0;count<5;count++)
pixelData[count]=FAULTY_CHARS[0][count];
|
To reliably use 'memcpy', you should declare the font as 'rom', rather
than 'const'. rom is designed to allow pointers to be constructed.
However I'm not sure (without checking), if memcpy would work even
then, since it is a rom ptr, not a ram ptr. |
|
|
nickdc
Joined: 19 Sep 2018 Posts: 15
|
|
Posted: Mon Jun 29, 2020 5:10 am |
|
|
Hello Ttelmah,
Thanks for your clues.
I changed 'const' to 'rom' and removed the memcpy.
If you are in the vicinity of Westvleteren, we will offer you a Trappist beer |
|
|
dluu13
Joined: 28 Sep 2018 Posts: 395 Location: Toronto, ON
|
|
Posted: Mon Jun 29, 2020 7:22 am |
|
|
nickdc wrote: | Hello Ttelmah,
Thanks for your clues.
I changed 'const' to 'rom' and removed the memcpy.
If you are in the vicinity of Westvleteren, we will offer you a Trappist beer |
Don't pass this up. They make some seriously good beer. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19538
|
|
Posted: Mon Jun 29, 2020 7:46 am |
|
|
Thanks for both the offer, and the recommendation.
Best Wishes |
|
|
newguy
Joined: 24 Jun 2004 Posts: 1909
|
|
Posted: Mon Jun 29, 2020 5:32 pm |
|
|
Ttelmah wrote: | Thanks for both the offer, and the recommendation.
Best Wishes |
I know some brewers that would trade their children for Westvleteren. |
|
|
dluu13
Joined: 28 Sep 2018 Posts: 395 Location: Toronto, ON
|
|
Posted: Mon Jun 29, 2020 5:35 pm |
|
|
newguy wrote: | Ttelmah wrote: | Thanks for both the offer, and the recommendation.
Best Wishes |
I know some brewers that would trade their children for Westvleteren. |
Here it's thirty bucks a bottle... If they happen to have it at the time. |
|
|
|
|
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
|