Advertisement
Guest User

Untitled

a guest
Feb 14th, 2020
116
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 7.08 KB | None | 0 0
  1. /*
  2.  ============================================================================
  3.  Name        : ex03.c
  4.  Author      : gbs
  5.  Version     :
  6.  Copyright   : Your copyright notice
  7.  Description : A simple C program for demonstrating the serial communication.
  8.  ============================================================================
  9.  */
  10.  
  11. //==============================================================================
  12. //                              USED INTERFACES
  13. //==============================================================================
  14.  
  15. #define _GNU_SOURCE             /* See feature_test_macros(7) */
  16.  
  17. #include <fcntl.h>              /* Required by open / write system calls.     */
  18. #include <pthread.h>            /* POSIX threads Library. Required by PIGPIO. */
  19. #include <stdint.h>             /* Standard Int Library.(uint32_t, uint8_t...)*/
  20. #include <stdio.h>              /* Standard Input/Ouput Library. (printf...)  */
  21. #include <stdlib.h>             /* General (standard) Library. (EXIT_SUCCESS. */
  22. #include <termios.h>            /* Terminal Input/Output interfaces.          */
  23. #include <unistd.h>             /* Complement (flags, constants, definitions..)
  24.                                     for the POSIX API. */
  25.  
  26. #include "pigpio.h"             /* PIGPIO Library header. */
  27.  
  28. //==============================================================================
  29. //                        MACROS AND DATATYPE DEFINITIONS
  30. //==============================================================================
  31.  
  32. /* HW and Interfaces */
  33.  
  34. #define SERIAL  "/dev/ttyS0"
  35. #define SERIAL_BAUD 115200
  36.  
  37. //==============================================================================
  38. //                     STATIC (PRIVATE) FUNCTION PROTOTYPES
  39. //==============================================================================
  40.  
  41. /**
  42.  * @brief A function to verify if any key was pressed on terminal.
  43.  *
  44.  * @return TRUE     If a key was pressed.
  45.  * @return FALSE    Otherwise.
  46.  */
  47. static int kbhit(void);
  48.  
  49. /**
  50.  * @brief Initializes the p_path serial device. Opens the serial device and
  51.  *        sets minimal attributes to get it working.
  52.  *
  53.  * @param[in] p_path    The serial device path.
  54.  * @param[out] p_fd     A file descriptor to link to the serial device above.
  55.  * @param[in] speed     The serial BAUDRATE.
  56.  *
  57.  * @return  1   If the serial device was initialized.
  58.  * @return  0   If an error has occurred.
  59.  */
  60. uint8_t serial_initialize(
  61.   const char *p_path,
  62.   int32_t *p_fd,
  63.   const uint32_t speed);
  64.  
  65.  
  66. //==============================================================================
  67. //                          STATIC GLOBAL VARIABLES
  68. //==============================================================================
  69.  
  70. //==============================================================================
  71. //                      IMPLEMENTATION OF PUBLIC FUNCTIONS
  72. //==============================================================================
  73.  
  74. int main(void)
  75. {
  76.   int serial_fd;            /* A file descriptor to manipulate the SERIAL.*/
  77.   uint8_t serial_st;        /* A status for the serial_initialize func.   */
  78.  
  79.   /* Opens SERIAL for reading and writing at SERIAL_BAUD baudrate.*/
  80.   serial_st = serial_initialize(SERIAL, &serial_fd, SERIAL_BAUD);
  81.  
  82.   if (serial_st == 0)
  83.   {
  84.     printf("Error: Failed to open serial %s \r\n", SERIAL);
  85.   }
  86.  
  87.   while(!kbhit())   /* While a key from the keyboard isn't pressed... */
  88.   {
  89.     write(serial_fd, "Running.. Serial is easy\r\n", sizeof("Running.. Serial is easy\r\n"));
  90.   }
  91.  
  92.   close(serial_fd);
  93.  
  94.   return EXIT_SUCCESS;
  95. }
  96.  
  97.  
  98. //==============================================================================
  99. //                IMPLEMENTATION OF STATIC (PRIVATE) FUNCTIONS
  100. //==============================================================================
  101.  
  102. static int kbhit(void)
  103. {
  104.   struct termios oldt, newt;
  105.  
  106.   int ch;
  107.   int oldf;
  108.  
  109.   /** Gets the attributes from the standard input file descriptor. */
  110.   tcgetattr(STDIN_FILENO, &oldt);
  111.  
  112.   /** Enables raw input. (unprocessed). */
  113.   newt = oldt;
  114.   newt.c_lflag &= ~(ICANON | ECHO);
  115.  
  116.   /** Sets the new attributes. */
  117.   tcsetattr(STDIN_FILENO, TCSANOW, &newt);
  118.  
  119.   /** Gets the file access mode and status flags. */
  120.   oldf = fcntl(STDIN_FILENO, F_GETFL, 0);
  121.  
  122.   /** Sets the same above read values + the O_NONBLOCK flag. */
  123.   fcntl(STDIN_FILENO, F_SETFL, oldf | O_NONBLOCK);
  124.  
  125.   /** Checks if there is a char on the standard terminal. (nonblock). */
  126.   ch = getchar();
  127.  
  128.   /** Make changes now, without waiting for data to complete. */
  129.   tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
  130.  
  131.   /** Removes the O_NONBLOCK flag. */
  132.   fcntl(STDIN_FILENO, F_SETFL, oldf);
  133.  
  134.   /** If any key was hitted, return true. And puts back the pressed key onto
  135.    *  the terminal. */
  136.   if(ch != EOF)
  137.   {
  138.     ungetc(ch, stdin);
  139.     return 1;
  140.   }
  141.  
  142.   return 0;
  143. }
  144.  
  145. uint8_t serial_initialize(
  146.   const char *p_path,
  147.   int32_t *p_fd,
  148.   const uint32_t speed)
  149. {
  150.  
  151.   uint8_t ret;
  152.  
  153.   /** Tries to open the serial device (p_path).
  154.    *  O_RDWR:     Request read and write permissions. */
  155.   *p_fd = open(p_path, O_RDWR);
  156.  
  157.   if (p_fd < 0)
  158.   {
  159.     printf("Error: Failed to open serial %s \n\n", p_path);
  160.     ret = 0;
  161.   }
  162.   else
  163.   {
  164.     printf("Serial (%s) opened!!\n\n", p_path);
  165.  
  166.     /** The structure to set and get the device parameters. */
  167.     struct termios config;
  168.  
  169.     /** Get the current configuration of the serial interface. */
  170.     if (tcgetattr(*p_fd, &config) < 0)
  171.     {
  172.       printf("Error: Could not get the %s attributes!\n\n", p_path);
  173.     }
  174.     else
  175.     {
  176.       printf("Serial (%s) attributes read.. \n\n", p_path);
  177.  
  178.       /** Check if the fd is pointing to a TTY device or not. */
  179.       if (!isatty(*p_fd))
  180.       {
  181.         printf("Error: %s isnt pointing to a TTY device!!\n\n", p_path);
  182.       }
  183.       else
  184.       {
  185.         printf("%s is a tty device. Continuing...\n\n", p_path);
  186.  
  187.         /** Setting the baudrate. */
  188.         if (cfsetspeed(&config, (speed_t)speed) < 0)
  189.         {
  190.           printf("Error: Couldn't set the %s baudrate!!\n\n", p_path);
  191.         }
  192.         else
  193.         {
  194.           /** No parity. */
  195.           config.c_cflag     &=  ~PARENB;
  196.           /** One stop bit. */
  197.           config.c_cflag     &=  ~CSTOPB;
  198.           /** Zeroes the char size mask. */
  199.           config.c_cflag     &=  ~CSIZE;
  200.           /** Sets data size = 8 bits. */
  201.           config.c_cflag     |=  CS8;
  202.           /** Disables HW flow control. */
  203.           config.c_cflag     &=  ~CRTSCTS;
  204.           /** Minimum number of characters for read. */
  205.           config.c_cc[VMIN]   =  1;
  206.           /** Timeout in deciseconds for read. (0.5s) */
  207.           config.c_cc[VTIME]  =  5;
  208.           /** Enables READ and ignores control lines. */
  209.           config.c_cflag     |=  CREAD | CLOCAL;
  210.  
  211.           /** Set the terminal to "raw mode". */
  212.           cfmakeraw(&config);
  213.  
  214.           /** Flushes the serial dev and sets the new attributes. */
  215.           if (tcsetattr(*p_fd, TCSAFLUSH, &config) < 0)
  216.           {
  217.             printf("Error: Couldn't set the %s attributes!!\n\n",
  218.               p_path);
  219.           }
  220.           else
  221.           {
  222.             ret = 1;
  223.           }
  224.         }
  225.       }
  226.     }
  227.   }
  228.   return ret;
  229. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement