1

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).

10
  • 1
    Consider using '0' and '9' (and >= and <=) instead of 47 and 58. Commented Mar 21, 2012 at 10:48
  • I don't see g_rx_idx being incremented in this snippet, while you seem to be consuming a byte. Maybe your cyclic buffer management code gets stuck somewhere (maybe here)? Commented Mar 21, 2012 at 10:50
  • 1
    You should use isdigit() to detect digits, don't hard-code encoded values. If you don't have isdigit(), use @pmg's suggestion. Commented Mar 21, 2012 at 12:11
  • @ pmg, unwind: That does not fix it. It does enter the if statement where it compares the ascii value with the values of digits 0 to 9. A string with the right values is also properly generated, but as soon as it's printed in the terminal, it does not react to any user input anymore. Also the cursor is placed halfway on the next line. This leads me to believe that the printf function does not know when to stop printing and gets stuck there. Commented Mar 21, 2012 at 13:17
  • @wildplasser: g_rx_idx should not be incremented, it just holds the input character code in the buffer at that location. Commented Mar 21, 2012 at 13:19

2 Answers 2

1

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 */ } } 
Sign up to request clarification or add additional context in comments.

2 Comments

Alright this works, thanks! The sprintf function did the job, I also editted the string lengths.
As a wijze raad: don't edit the string lengths. Let the compiler do the calculations for you, either by strlen() or by sizeof buff -1
0

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).

1 Comment

When I place printf() outside the handler, in the main while loop with a bool it still gives the same error. You're right about the char values, silly me. I used sprintf() mentioned by wildplasser to automatically convert them!

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.