Reading a number from UART (CY8CKIT-044 version)

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
lock attach
Attachments are accessible only for community members.
MotooTanaka
Level 9
Level 9
Distributor - Marubun (Japan)
First comment on blog Beta tester First comment on KBA

Hi,

こんばんは、

As I have written some CLI programs, I wished that I want to enter a number as dec, hex, bin.

And if I can change the width(size) of a word it would be even better.

CLI タイプのサンプルを書いてきましたが、数字を入力するときに2進、10進、16進で入れることができたらと思っていました。

更に、ワードのサイズも変更できたら便利だろなと。

So I gave it a try using CY8CKIT-044.

Until I started debugging the program, I was thinking that this was going to be an easy project.

But PSoC 4 taught me that I was wrong.

I cheated by using my tty utils sample, but most of the newly written functions in the main.c should work with other MCUs, I hope.

Re: tty_utils a utility sample for CLI type program

というわけで、CY8CKIT-044 を使って試してみました。

デバッグを始めるまでは、これは簡単なサンプルになるだろうな~と、軽く構えていたのですが。

自分が間違っていたことを PSoC 4 に教えられました。

UART 入出力の分部は以前に書いた tty utils サンプルを使って楽をしましたが、今回 main.c 内で書いた新しい関数は

恐らく他の MCU でも機能するのではないかと思います。

Re: tty_utils a utility sample for CLI type program

Since this program was newly written, there may (must) be bugs.

In case you find one (or more), please notify me using the reply to this discussion.

(Although I can not guarantee how fast I will be able to fix it...)

如何せん書きたてのプログラムですので、バグがあるかも知れません (いや、きっとあるでしょう)。

もし、見つけられた方はレスで知らせていただけると幸いです。

(直ぐに治せるかについては保証できないのですが・・・)

Tera Term log

001-tera_term_log.JPG

Schematic

002-schematic.JPG

Pins

003-pins.JPG

main.c

==================

#include "project.h"

#include "stdio.h"

#include "tty_utils.h"

int word_width = 32 ;

void init_hardware(void)

{

    tty_init() ;

    CyGlobalIntEnable; /* Enable global interrupts. */

}

void usage(void)

{

    print("=== usage ===\n\r") ;

    print("Enter number as\n\r") ;

    print("hex: Start with 0x or 0X \"0xABCD\"\n\r") ;

    print("bin: Start with 0b or 0B \"0b1010\"\n\r") ;

    print("dec: Start with 0d or 0D or number \"0d123\" or \"123\"\n\r") ;

    print("width <word_width> : set word witdh\n\r") ;

    print("help : show this message\n\r") ;

    snprintf(str, STR_BUF_LEN, "Current word width = %d\n", word_width) ;

    print(str) ;

    print("=============\n\r") ;

}

void syntax_error(char *str)

{

    print("Syntax Error: ") ;

    print(str) ;

    print("\n\r") ;

}

int32_t read_bin(char *str)

{

    int32_t number = 0 ;

    while(*str) {

        number <<= 1 ;

        switch(*str) {

        case '0':

            break ;

        case '1':

            number |= 1u ;

            break ;

        default:

            syntax_error(str) ;

            break ;

        }

        str++ ;

    }

    return( number ) ;

}

void get_word_width(char *str)

{

    int tmp_width ;

    sscanf(str, "%*s %d", &tmp_width) ;

    if ((32 >= tmp_width) && (tmp_width >= 1)) {

        print("Word Width is set to: ") ;

        snprintf(str, STR_BUF_LEN, "%d\n\r", tmp_width) ;

        print(str) ;

        word_width = tmp_width ;

    } else {

        syntax_error(str) ;

    }

    return ;

}

void sign_extend(uint32_t *number, int word_width)

{

    uint32_t sign ;

    int i, up_to ;

   

    sign = *number & (1u << (word_width - 1)) ;

    if (8 >= word_width) {

        up_to = 8 ;

    } else if ((16 >= word_width)&&(word_width > 8)) {

        up_to = 16 ;    

    } else {

        up_to = 32 - word_width ;         

    }

    for (i = 0 ; i < up_to ; i++ ) {

            sign <<= 1 ;

            *number |= sign ;

    }

}

           

int32_t get_number(char *str)

{

    int32_t number = 0 ;

    if ((str[0] == '0') && (strlen(str) >= 3)) {

        switch(str[1]) {

        case 'b': // binary

        case 'B':

            number = read_bin(&str[2]) ;

            break ;

        case 'd': // decimal

        case 'D':

            sscanf(str, "%d", &number) ;

            break ;

        case 'x': // hexadecimal

        case 'X':

            sscanf(str, "%x", &number) ;

            break ;

        default:

            syntax_error(str) ;

            break ;

        }

    } else { /* default, trying as a decimal */

            sscanf(str, "%d", &number) ;

    }

    return(number) ;          

}

void print_as_bin(uint32_t unum)

{

    uint32_t mask ;

    mask = 1u << (word_width - 1) ;

    while(mask) {

        if (unum & mask) {

            print("1") ;

        } else {

            print("0") ;

        }

        mask >>= 1 ;

    }

}

void print_a_number(int32_t number)

{

    uint32_t ext_num ;

    char hex_format[32] ;

    int hex_digit = 0 ;

    int i ;

    uint32_t mask = 0 ;

   

    ext_num = number ;

    print("Hex: ") ;

    hex_digit = (word_width + 3) / 5 ;

    snprintf(hex_format, 31, "0x%%0%dX ", hex_digit) ;

    for (i = 0 ; i < word_width ; i++ ) {

        mask <<= 1 ;

        mask |= 1 ;

    }

    if (word_width > 16) {

        snprintf(str, STR_BUF_LEN, hex_format, (uint32_t)(number & mask)) ;

    } else if ((16 >= word_width)&&(word_width > 8)) {

        snprintf(str, STR_BUF_LEN, hex_format, (uint16_t)(number & mask)) ;

    } else if (8 >= word_width) {

        snprintf(str, STR_BUF_LEN, hex_format, (uint8_t)(number & mask)) ;      

    }

    print(str) ;

    print("Unsigned: ") ;

    if (word_width > 16) {

        snprintf(str, STR_BUF_LEN, "%u ", (uint32_t)(number & mask)) ;

    } else if ((16 >= word_width)&&(word_width > 8)) {

        snprintf(str, STR_BUF_LEN, "%u ", (uint16_t)(number & mask)) ;

    } else if (8 >= word_width) {

        snprintf(str, STR_BUF_LEN, "%u ", (uint8_t)(number & mask)) ;      

    }

    print(str) ;

    print("Signed: ") ;

    sign_extend(&ext_num, word_width) ;

    if (word_width > 16) {

        snprintf(str, STR_BUF_LEN, "%d ", (int32_t)ext_num) ;

    } else if ((16 >= word_width)&&(word_width > 8)) {

        snprintf(str, STR_BUF_LEN, "%d ", (int16_t)ext_num) ;

    } else if (8 >= word_width) {

        snprintf(str, STR_BUF_LEN, "%d ", (int8_t)ext_num) ;      

    }

    print(str) ;

    print("Bin: ") ;

    print_as_bin(number) ;

    print("\n\r") ;

}

int main(void)

{

    int32_t number ;

    init_hardware() ;

    splash("tty get number test") ;

    usage() ;

    prompt() ;

    for(;;) {

        if (get_line()) { // got a line

            switch(str[0]) {

            case 'w': case 'W':

                get_word_width(str) ;

                break ;

            case '0': case '1': case '2': case '3': case '4':

            case '5': case '6': case '7': case '8': case '9':

            case '-':

                number = get_number(str) ;

                print_a_number(number) ;

                break ;

            case 'h': case 'H':

            default:

                usage() ;

                break ;

            }

            prompt() ;

        }

    }

}

==================

21-Jul-2020

moto

1 Reply
DheerajK_81
Moderator
Moderator
Moderator
First comment on KBA First comment on blog 5 questions asked

Hello MoTa_728816​,

This is a great value add. Thank you for sharing this project with the community!

Regards,
Dheeraj