Question

I'm trying to capture input number through input UART event handler and print it back with some multiplications of that number. It prints the string just fine, but after it has printed the program does not react to any input anymore. It is possible to print the alfabet or display an error message, but when I use the printf function the terminal stops responding to input and the cursor is placed halfway on the next line.

This is the C code:

#include "mss_uart.h"
#include <stdio.h>

#define RX_BUFF_SIZE    64
#define MSS_UART_57600_BAUD     57600
uint8_t g_rx_buff[RX_BUFF_SIZE];
uint8_t g_rx_idx;

void uart0_rx_handler( mss_uart_instance_t * this_uart )
{
MSS_UART_get_rx( &g_mss_uart0, &g_rx_buff[g_rx_idx], sizeof(g_rx_buff) );
if(g_rx_buff[g_rx_idx] > 96 && g_rx_buff[g_rx_idx] < 123)
{
    uint8_t message[55] = "De letter was: x, de uppercase letter van : x is y.\n\r";
    message[15] = g_rx_buff[g_rx_idx];
    message[44] = g_rx_buff[g_rx_idx];
    message[49] = g_rx_buff[g_rx_idx] - 32;

    MSS_UART_polled_tx( &g_mss_uart0, message, sizeof(message) );
}
else if(g_rx_buff[g_rx_idx] > 64 && g_rx_buff[g_rx_idx] < 91)
{
    uint8_t message[55] = "De letter was: x, de lowercase letter van : x is y.\n\r";
    message[15] = g_rx_buff[g_rx_idx];
    message[44] = g_rx_buff[g_rx_idx];
    message[49] = g_rx_buff[g_rx_idx] + 32;

    MSS_UART_polled_tx( &g_mss_uart0, message, sizeof(message) );
}
else if(g_rx_buff[g_rx_idx] > 47 && g_rx_buff[g_rx_idx] < 58)
{
    int number = g_rx_buff[g_rx_idx] - '0';
            int number2 = number * number;
            int number3 = number2 * number;
            int number4 = number3 * number;

    printf("Getallenreeks: %d, %d, %d, %d.\n\r", number, number2, number3, number4);

}
else
{
    uint8_t message[10] = "Error.\n\r";
    MSS_UART_polled_tx( &g_mss_uart0, message, sizeof(message) );
}
}

int main(void)
{
MSS_UART_init
(
        &g_mss_uart0,
        MSS_UART_57600_BAUD,
        MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT
);

MSS_UART_set_rx_handler( &g_mss_uart0, uart0_rx_handler, MSS_UART_FIFO_SINGLE_BYTE    );

while ( 1 )
{}
return(0);
}

void uart0_rx_handler is the intterupt handler and MSS_UART_get_rx puts the input in g_rx_buff[g_rx_idx].

I tried printing the numbers with the same MSS_UART_polled_tx function I use for the characters but no luck. It prints the wrong ascii values:

if(g_rx_buff[g_rx_idx] > 47 && g_rx_buff[g_rx_idx] < 58)
{
    int number = g_rx_buff[g_rx_idx] - '0';
    int number2 = number * number;
    int number3 = number2 * number;
    int number4 = number3 * number;

    uint8_t message[15] = "Getallenreeks: ";
    uint8_t komma[2] = ", ";
    uint8_t end[5] = ".\n\r";

    char numberstring2[2];
    char numberstring3[3];
    char numberstring4[4];

    sprintf(numberstring2, "%d", number2);
    sprintf(numberstring3, "%d", number3);
    sprintf(numberstring4, "%d", number4);

    uint8_t messagenumber[1];
    uint8_t messagenumber2[1];
    uint8_t messagenumber3[1];
    uint8_t messagenumber4[1];

    messagenumber[0] = '0' + number;
    messagenumber2[0] = '0' + number2;
    messagenumber3[0] = '0' + number3;
    messagenumber4[0] = '0' + number4;      

    http://imageshack.us/photo/my-images/843/testlan.jpg/( &g_mss_uart0, message, sizeof(message) );
    MSS_UART_polled_tx( &g_mss_uart0, messagegetal, sizeof(messagenumber) );
    MSS_UART_polled_tx( &g_mss_uart0, komma, sizeof(komma) );
    MSS_UART_polled_tx( &g_mss_uart0, messagegetal2, sizeof(messagenumber2) );
    MSS_UART_polled_tx( &g_mss_uart0, komma, sizeof(komma) );
    MSS_UART_polled_tx( &g_mss_uart0, messagegetal3, sizeof(messagenumber3) );
    MSS_UART_polled_tx( &g_mss_uart0, komma, sizeof(komma) );
    MSS_UART_polled_tx( &g_mss_uart0, messagegetal4, sizeof(messagenumber4) );
    MSS_UART_polled_tx( &g_mss_uart0, end, sizeof(end) );       
 }

Code output example: http://imageshack.us/photo/my-images/843/testlan.jpg/ Left terminal shows use of the printf function, right terminal shows use of the MSS_UART_polled_tx function for numbers (shown in the second code block).

Was it helpful?

Solution

I think the biggest error was counting the length of "\r\n" as 4 (it is 2), the other is using `sizeof stringarray', which includes the space used by the terminating NUL-byte.

  /** added */
#include <stdint.h>
#include <stdio.h>

struct xx;
typedef struct xx mss_uart_instance_t;

void MSS_UART_get_rx( mss_uart_instance_t * the_uart, uint8_t buff[] , size_t len );
void MSS_UART_polled_tx( mss_uart_instance_t * the_uart, uint8_t buff[] , size_t len );
    /** End added */

#define RX_BUFF_SIZE    64
#define MSS_UART_57600_BAUD     57600

uint8_t g_rx_buff[RX_BUFF_SIZE];
uint8_t g_rx_idx;

void uart0_rx_handler( mss_uart_instance_t * this_uart )
{
    MSS_UART_get_rx( this_uart, &g_rx_buff[g_rx_idx], sizeof g_rx_buff );
    if(g_rx_buff[g_rx_idx] >= 'a' && g_rx_buff[g_rx_idx] <= 'z')
    {
        uint8_t message[] = "De letter was: x, de uppercase letter van : x is y.\n\r";
        message[15] = g_rx_buff[g_rx_idx];
        message[44] = g_rx_buff[g_rx_idx];
        message[49] = g_rx_buff[g_rx_idx] - ('a' - 'A');

        MSS_UART_polled_tx( this_uart, message, strlen(message) ); /* 52 */
    }
    else if(g_rx_buff[g_rx_idx] >= 'A' && g_rx_buff[g_rx_idx] <= 'Z' )
    {
        uint8_t message[] = "De letter was: x, de lowercase letter van : x is y.\n\r";
        message[15] = g_rx_buff[g_rx_idx];
        message[44] = g_rx_buff[g_rx_idx];
        message[49] = g_rx_buff[g_rx_idx] + ('a' - 'A');

        MSS_UART_polled_tx( this_uart, message, strlen(message) ); /* 52 */
    }
    else if(g_rx_buff[g_rx_idx] >= '0' && g_rx_buff[g_rx_idx] <= '9')
    {
        uint8_t bigbuff[70] ;
        size_t buflen;
        int number = g_rx_buff[g_rx_idx] - '0';
                int number2 = number * number;
                int number3 = number2 * number;
                int number4 = number3 * number;

        buflen = sprintf(bigbuff, "Getallenreeks: %d, %d, %d, %d.\n\r", number, number2, number3, number4);
        MSS_UART_polled_tx( this_uart, bigbuff, buflen );

    }
    else
    {
        uint8_t message[] = "Error.\n\r";
        MSS_UART_polled_tx( this_uart, message, strlen(message) ); /* 8 */
    }
}

OTHER TIPS

I think you have two problems.

One is that you're calling printf() inside an interrupt handler and it's hanging. Perhaps on your platform printf() can't be called from interrupt context, because (guessing) it tries to use interrupt-driven output and waits for a completion interrupt which never comes because you have interrupts disabled.

Second problem is to do with your expectations about the output from the second example. They look OK to me. You are multiplying up some pretty large numbers then adding them to a char value. This will result in a single character which may be a letter or symbol that you don't want. For example

'0' + 16 == '@'

Which you see in one of your examples. If you want to output "16", that is two characters '1' and '6', and you need to do some more work to calculate individual characters (involving division by 10).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top