0
votes

I have a piece of code that runs on an embedded system. Its job is to convert some ASCII characters into proprietary data. The data is stored in a multi-dimensional array and what appears to be the problem, although I am unable to confirm this with the hardware debugger, is that the bit variable is staying at value 2. This code works the first two times it is run, but on the third run it breaks and returns starts sending wrong data through the UART interface. I though maybe someone else analyzing this might be able to see what I'm missing. This is C99 which I am not too familiar with. Bleow is the entire function, but I think the problem is with the for statement?? Any help would be greatly appreciated!

void simple_uart_putstring(uint8_t *str, uint16_t length)
{
    //send data bits
    uint_fast8_t index = 0;
    uint8_t ch = str[index++];
    uint_fast8_t bitCount = 0;
    int index2 = 0;
    int bit = 0;

    if (length > 1)
    {
        while (length >= index)
        {
            if (bitCount < 2)
            {
                if (length < 10)
                {
                    //send sync bits
                    simple_uart_put(254);
                    simple_uart_put(223);
                    bitCount = 2;
                } else {
                    //send sync bits and add scrolling
                    simple_uart_put(254);
                    simple_uart_put(222);
                    bitCount = 2;
                }
            }
            //send each bit for each letter in the string
            for (uint_fast8_t i = 0; i < 5; i++)
            {
                index2 = (int)ch;
                bit = (int)i;
                simple_uart_put(matrix[index2 - 32][bit]);
                bitCount++;
            }
            ch = str[index++];
        }
        //the main controller is expecting 150 bits total to continue to send bit until 150
        while (bitCount <= 150)
        {
            simple_uart_put(0);
            bitCount++;
            if(bitCount >= 150)
            {
                bitCount = 0;
                break;
            }
        }
        bitCount = 0;
    }
}

And here is a sample of the array:

 const uint8_t matrix[59][5] = 
    {
        { 0, 0, 0, 0, 0}, //space  
        { 0, 125, 0, 0, 0}, //!  
        { 0, 112, 0, 112, 0}, //"
{127, 127, 127, 127, 127 }, //# 
                                           { 18, 42, 107, 36, 0}, //$
                                           { 50, 52, 22, 38, 0}, //%
                                           { 38, 89, 57, 6, 9}, //&
                                           { 64, 48, 0, 0, 0}, //'
                                           { 0, 0, 62, 65, 0}, //(
                                           { 0, 65, 62, 0, 0}, //)
                                           { 20, 8, 62, 8, 20}, //*
                                           { 0, 8, 28, 8, 0}, //+
                                           { 1, 6, 0, 0, 0}, //,
                                           { 0, 8, 8, 8, 0}, //-
                                           { 3, 3, 0, 0, 0}, //.
                                           { 2, 4, 8, 16, 32}, //
                                           { 62, 69, 73, 62, 0}, //0
                                           { 1, 33, 127, 1, 0}, //1
                                           { 35, 67, 69, 49, 0}, //2
                                           { 34, 73, 73, 54, 0}, //3
                                           { 12, 20, 36, 127, 0}, //4
                                           { 114, 81, 81, 78, 0}, //5
                                           { 30, 41, 73, 6, 0}, //6
                                           { 64, 71, 72, 112, 0}, //7
                                           { 54, 73, 73, 54, 0}, //8
                                           { 48, 73, 74, 60, 0}, //9
                                           { 0, 54, 54, 0, 0}, //:
                                           { 0, 1, 54, 0, 0}, //;
                                           { 0, 8, 20, 34, 0}, //<
                                           { 0, 20, 20, 20, 0}, //=
                                           { 0, 34, 20, 8, 0}, //>
                                           { 32, 64, 69, 72, 48}, //?
                                           { 62, 65, 93, 93, 112}, //@

                                           { 63, 72, 72, 63, 0 }, //a
                                           { 127, 73, 73, 54, 0 }, //b
                                           { 62, 65, 65, 34, 0}, //c
                                           { 127, 65, 34, 28, 0 }, //d
                                           { 127, 73, 73, 65, 0}, //e
                                           { 127, 72, 72, 64, 0}, //f
                                           { 62, 65, 73, 47, 0}, //g
                                           { 127, 8, 8, 127, 0}, //h
                                           { 0, 65, 127, 65, 0},//i
                                           { 6, 65, 126, 64, 0}, //j
                                           { 127, 8, 20, 99, 0}, //k
                                           { 127, 1, 1, 1, 0}, //l
                                           { 127, 32, 24, 32, 127}, //m
                                           { 127, 16, 8, 127, 0}, //n
                                           { 62, 65, 65, 62, 0}, //o
                                           { 127, 72, 72, 48, 0}, //p
                                           { 60, 70, 66, 61, 0}, //q
                                           { 127, 76, 74, 49, 0}, //r
                                           { 50, 73, 73, 38, 0}, //s
                                           { 0, 64, 127, 64, 0}, //t
                                           { 126, 1, 1, 126, 0},
                                           { 127, 1, 2, 124, 0},
                                           { 126, 1, 6, 1, 126},
                                           { 99, 28, 28, 99, 0},
                                           { 112, 8, 8, 127, 0},
                                           { 71, 73, 81, 97, 0}};

And the uart send method:

void simple_uart_put(uint8_t cr)
{
  NRF_UART0->TXD = (uint8_t)cr;

  while (NRF_UART0->EVENTS_TXDRDY!=1)
  {
    // Wait for TXD data to be sent
  }

  NRF_UART0->EVENTS_TXDRDY=0;
}

An example of this working would be if the input string is "AB" and the length = 2; It should send the following bytes via UART:

{254, 223, 63, 72, 72, 63, 0, 127, 73, 73, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, etc....} 

The first two bytes are sync bytes, the next five come from the array matrix[33][0 to 4] because ASCII 'A' = 65 and 65-32 = 33. Then the next five come from ASCII 'B' = 66 and 66 - 32 = 34 so they are sent from matrix[34][0 to 4]. Then the next n = 150 - bitNumber are sent as 0 because the main controller is expecting 150 bytes always.

1
It's very difficult to know what the problem is unless you tell us what it's meant to do. What is the on-the-wire protocol? - abligh
I'm not sure what you are looking for, but I haven ow added a few code comments. The purpose of this method is to convert a string into data for a matrix display, then pass it along to the display controller via UART. - Tanner Ewing
This is not a complete function. Edit your post with the complete function, including argument list and return type, just as it is in your project. That would help to follow input to output. Include an example of (a non-proprietary example) of a typical input value that this function would be expected to process. - ryyker
I have included the parameters, and this function has no return type (void) I have added the simple_uart_put method as well now - Tanner Ewing
The problem shouldn't be in the for statement unless somehow casting uint_fast8_t to int isn't compatible. This seems like a hard to believe scenario. - dbeer

1 Answers

1
votes

See edit at bottom

Without having definitions for all functions, I cannot completely analyze this, however there are a couple of suspicious things:

1) this declaration is odd:

  uint_fast8_t index = 0;
  uint8_t ch = str[index++]; //always sets ch to first character of input "str" then increments index.  

NOTE: corrected comment on previous line.

2) although the comment indicates "each bit for each letter in the string" it only handle 5:

        for (uint_fast8_t i = 0; i < 5; i++){...} //what if lenth of input is less than 5? 

Suggest changing to:

        for (uint_fast8_t i = 0; i < length; i++){...}  //used second argument "length"  

3) Finally, it seems that null terminating the string should follow the for loop, but: (see comments in line) (Also, input arguments used were "abc", 4)

    for (uint_fast8_t i = 0; i < 5; i++)
    {
        index2 = (int)ch; //ch inits to first char in str, and indexes through
        bit = (int)i;
        //simple_uart_put(matrix[index2 - 32][bit]);
        bitCount++;
    }
    ch = str[index++]; //terminates in second character of input "b' in this case  
    //I think this should null terminate with '\0' if it is to be treated as a C string,
    //but because, as you say, this is "proprietary", I am not sure.  

EDIT

I think the problem may be that you have declared the variable matrix with what looks like sufficient room, but only initialized it with three rows of data:

const uint8_t matrix[59][5] = 
{
    { 0, 0, 0, 0, 0}, //space  
    { 0, 125, 0, 0, 0}, //!  
    { 0, 112, 0, 112, 0}, //"
}; //have only initialized matrix[0], matrix[1] and matrix[2]  

The remaining 53 rows of data, although owned by you, have not been initialized that I can see. So, when you say:

the next five come from the array matrix[33][0 to 4] because ASCII 'A' = 65 and 65-32 = 33. Then the next five come from ASCII 'B' = 66 and 66 - 32 = 34 so they are sent from matrix[34][0 to 4]

That suggests what ever random number happens to be occupying those uninitialized memory locations, are what is being written out in the line:

simple_uart_put(matrix[index2 - 32][bit]);

EDIT 2 (See comment to explain)

Here is my main(), and commented simple_uart_putstring():

int     main()
{
    uint8_t *str;
    int len=3;

    str = malloc(3); //extra char for terminating null byte

    strcpy(str, "AB");
    simple_uart_putstring(str, 2);
    free(str);
}

void simple_uart_putstring(uint8_t *str, uint16_t length)
{
    //send data bits
  uint_fast8_t index = 0;
  uint8_t ch = str[index++]; //ch inits to first char in str, and indexes through
    uint_fast8_t bitCount = 0;
    int index2 = 0;
    int bit = 0;

    if (length > 1)
    {
        while (length >= index)
        {
            if (bitCount < 2)
            {
                    if (length < 10)
                    {
                        //send sync bits
                        //simple_uart_put(254);
                        //simple_uart_put(223);
                        bitCount = 2;
                    } else {
                        //send sync bits and add scrolling
                        //simple_uart_put(254);
                        //simple_uart_put(222);
                        bitCount = 2;
                    }   
            }
            //send each bit for each letter in the string
            for (uint_fast8_t i = 0; i < 5; i++)
            {
                index2 = (int)ch; //
                bit = (int)i;
                /*simple_uart_put(*/matrix[index2 - 32][bit];//);break here to view "matrix[index2 - 32][bit]"
                bitCount++;
            }
            ch = str[index++]; //
        }
        //the main controller is expecting 150 bits total to continue to send bit until 150
            while (bitCount <= 150)
        {
                //simple_uart_put(0);
                bitCount++;
                if(bitCount >= 150)
                {
                    bitCount = 0;
                    break;
                }
        }
        bitCount = 0;
    }
}