1 Reply Latest reply on Jul 21, 2020 5:25 AM by DheerajK_81

    Reading a number from UART (CY8CKIT-044 version)

    MoTa_728816

      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