DarkElvenAngel
Posts: 1744
Joined: Tue Mar 20, 2018 9:53 pm

[SOLVED] Problem filling my array [BUT WHY?]

Tue Jun 15, 2021 5:04 am

Hello Everyone,

I have a function that is suppose to fill and array nibble by nibble but it doesn't work for some reason.

Code: Select all

bool _Prase_ESC(char data)
{
    static uint8_t count = 0;
    static byte char_data[9] = { 0 };
    if (count == 0) { char_data[0] = data; count++; return 1; }  
    char_data[((count - 1)  / 2) + 1] |= ((data & 0x0f) << ( 8 * count % 2));          
    if (count == 16 )
    {
           Define_User_Char(char_data[0], &char_data[1]);
           memset(char_data,0,9);
           count = 0;
           return true;
     }
     count++;
     return false;
}
The char_data array only ever has the low nibble set the high nibble is always 0.

I've rewritten this 10 different ways and the result is always the same.

This code fragment of the function is the important part, this part is triggered correctly and ends when it should the problem is the data is half missing.

I've tested this with a string ajjee````````jjee and that should reproduce
0x61 0xaa, 0x55, 0x00, 0x00, 0x00, 0x00, 0xaa, 0x55
what I get is
0x61 0x0a, 0x05, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x05

What am I missing? (besides half the data)
Last edited by DarkElvenAngel on Tue Jun 15, 2021 3:06 pm, edited 1 time in total.

Memotech Bill
Posts: 135
Joined: Sun Nov 18, 2018 9:23 am

Re: Problem filling my array

Tue Jun 15, 2021 7:23 am

A nibble is only four bits, not eight.

Try:

Code: Select all

char_data[((count - 1)  / 2) + 1] |= ((data & 0x0f) << ( 4 * count % 2));

DarkElvenAngel
Posts: 1744
Joined: Tue Mar 20, 2018 9:53 pm

Re: [SOLVED] Problem filling my array [BUT WHY?]

Tue Jun 15, 2021 3:26 pm

So yes coding when you are tired isn't a good idea and a nibble is 4 and not 8.

But that didn't work! I don't know if there is a compiler bug or what but what I had to do to get it to work was this.

Code: Select all

bool _Prase_ESC(char data)
{
    static uint8_t count = 0;
    static uint8_t params[2] = { 0 };
    if (count == 0)
    {
          params[0] = data - FONTSET_START ; 
          if (params[0] >= FONTSET_SIZE) return false;
          Clear_User_Char(data);
          count++;
          return 1; 
    }
    data &= 0xf;
    data <<= 4 * (count % 2);
    USR_FONT[(params[0] * 8) +  ((count - 1)  / 2) ] |= data;
    if (count == 16 )
    {
           count = 0;
           return true;
     }
     count++;
     return false;
}   
No combination of doing that in one line would work. Trouble shooting this was a real pain I thought the most effective method was to load the values straight into RAM and not buffer them then I could see how the buffer would fill as I entered them.

Any idea as to why this solution didn't work
Memotech Bill wrote: A nibble is only four bits, not eight.

Try:

Code: Select all

char_data[((count - 1)  / 2) + 1] |= ((data & 0x0f) << ( 4 * count % 2));
It's the same code but it will never shift the bits the shift is always 0

User avatar
jojopi
Posts: 3490
Joined: Tue Oct 11, 2011 8:38 pm

Re: [SOLVED] Problem filling my array [BUT WHY?]

Tue Jun 15, 2021 3:47 pm

DarkElvenAngel wrote:
Tue Jun 15, 2021 3:26 pm
data <<= 4 * (count % 2);

((data & 0x0f) << ( 4 * count % 2));
* and % have the same precedence and associate from left from right. You need the parentheses around the modulo.

Or (count % 2 * 4), but that may be not the best style.

vikK4yHabbe7L
Posts: 22
Joined: Sun Jan 31, 2021 3:33 pm

Re: [SOLVED] Problem filling my array [BUT WHY?]

Wed Jun 23, 2021 6:57 pm

I like my code wordier but simpler:

Code: Select all

indx = count / 2;  // where to put it
if ( count & 1 ) {
	buf[indx] = data;   // save bottom nibble
} else {
	buf[indx] |= data << 4;  // add top nibble
}
count++;
Mike /

pic0
Posts: 53
Joined: Tue Jan 26, 2021 11:04 am

Re: [SOLVED] Problem filling my array [BUT WHY?]

Wed Jun 23, 2021 7:23 pm

Sure?

Starting with count=0 the first assignment will be

Code: Select all

 	buf[0] |= data << 4;  // add top nibble
and the second after incrementing count will be

Code: Select all

	buf[0] = data;   // save bottom nibble
and overwrite the previous one. So in my opinion the if condition needs to be inverted

DarkElvenAngel
Posts: 1744
Joined: Tue Mar 20, 2018 9:53 pm

Re: [SOLVED] Problem filling my array [BUT WHY?]

Wed Jun 23, 2021 8:10 pm

Index 0 was used to hold the index where the data was going to be stored.

0 = Index
1 - 16 = data

now I've change things to be

Code: Select all

if (count == 0)
{
       params[0] = data
       count++;
       return 1;
}
data = strtol(&data,NULL,16);
USR_FONT[(params[0] * 8) +  ((count - 1)  / 2) ] |= data << (4 * (count % 2));
count++;
USR_FONT being where the buffer was to be copied after it was fully processed I just cut out the buffer

The trip up was the order of operations

Return to “SDK”