FelipeMdeO commented on code in PR #2820:
URL: https://github.com/apache/nuttx-apps/pull/2820#discussion_r1957443481


##########
examples/spislv_test/spislv_test.c:
##########
@@ -22,81 +22,558 @@
  * Included Files
  ****************************************************************************/
 
-#include <nuttx/config.h>
 #include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
 #include <fcntl.h>
-#include <unistd.h>
 #include <errno.h>
-#include <string.h>
-#include <stdlib.h>
+#include <unistd.h>
+#include <ctype.h>
+#include <sys/select.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Define buffer sizes */
+#define RX_BUFFER_SIZE 64
+#define TX_BUFFER_SIZE 64
+#define SOURCE_FILE "dev/spislv2" /* SPI device path */
+
+/* Enumeration for operation modes */
 
-#define SOURCE_FILE "/dev/spislv2"
-#define BUFFER_SIZE 256
+typedef enum
+{
+  MODE_WRITE,
+  MODE_LISTEN,
+  MODE_ECHO,
+  MODE_INVALID
+} operation_mode_t;
 
 /****************************************************************************
- * Public Functions
+ * Structure to hold program configurations
  ****************************************************************************/
 
+typedef struct
+{
+  operation_mode_t mode;
+  int num_bytes;            /* Applicable for write mode */
+  int timeout_seconds;      /* Applicable for all modes */
+  unsigned char tx_buffer[TX_BUFFER_SIZE];
+} program_config_t;
+
 /****************************************************************************
- * spislv_test
+ * Private Functions
  ****************************************************************************/
 
-int main(int argc, FAR char *argv[])
+/**
+ * @brief Converts a single hexadecimal character to its byte value.
+ *
+ * @param c The hexadecimal character.
+ * @return The byte value of the hexadecimal character, or -1 if invalid.
+ */
+
+static int hexchar_to_byte(char c)
 {
-  int fd;
-  char buffer[BUFFER_SIZE];
-  ssize_t bytes_read;
-  ssize_t i;
+  if (c >= '0' && c <= '9')
+    {
+      return c - '0';
+    }
 
-  printf("Slave started!!\n");
-  fd = open(SOURCE_FILE, O_RDWR);
+  c = tolower(c);
 
-  if (fd < 0)
+  if (c >= 'a' && c <= 'f')
     {
-      printf("Failed to open %s: %s\n", SOURCE_FILE, strerror(errno));
-      return 0;
+      return c - 'a' + 10;
     }
 
-  while (1)
+  return -1;
+}
+
+/**
+ * @brief Converts a hexadecimal string to a byte array.
+ *
+ * @param hexstr The input hexadecimal string.
+ * @param bytes The output byte array.
+ * @param max_bytes The maximum number of bytes to convert.
+ * @return The number of bytes converted, or -1 on error.
+ */
+
+static int hexstr_to_bytes(const char *hexstr, unsigned char *bytes,
+                           size_t max_bytes)
+{
+  size_t len = strlen(hexstr);
+
+  if (len % 2 != 0 || len / 2 > max_bytes)
     {
-      /* Read the number from the source file */
+      return -1;
+    }
 
-      printf("Slave: Reading from %s\n", SOURCE_FILE);
-      bytes_read = read(fd, buffer, BUFFER_SIZE - 1);
+  for (size_t i = 0; i < len / 2; i++)
+    {
+      int high = hexchar_to_byte(hexstr[2 * i]);
+      int low  = hexchar_to_byte(hexstr[2 * i + 1]);
 
-      if (bytes_read < 0)
+      if (high == -1 || low == -1)
         {
-          printf("Failed to read from %s: %s\n",
-                    SOURCE_FILE, strerror(errno));
-          close(fd);
-          return 0;
+          return -1;
         }
-      else if (bytes_read > 0)
+
+      bytes[i] = (high << 4) | low;
+    }
+
+  return len / 2;
+}
+
+/**
+ * @brief Parses and validates command-line arguments.
+ *
+ * @param argc Argument count.
+ * @param argv Argument vector.
+ * @param config Pointer to the program configuration structure.
+ * @return 0 on success, -1 on failure.
+ */
+
+static int parse_arguments(int argc, char *argv[],
+                           program_config_t *config)
+{
+  int opt;
+
+  /* Set default configurations */
+
+  config->mode           = MODE_INVALID;
+  config->num_bytes      = 0;
+  config->timeout_seconds = 10; /* Default timeout */
+
+  /* Parse command-line options */
+
+  while ((opt = getopt(argc, argv, "x:t:le")) != -1)
+    {
+      switch (opt)
+        {
+          case 'x':
+            if (config->mode != MODE_INVALID)
+              {
+                fprintf(stderr,
+                        "Error: Multiple operation modes specified.\n");
+                return -1;
+              }
+
+            config->mode = MODE_WRITE;
+            config->num_bytes = atoi(optarg);
+            if (config->num_bytes <= 0 ||
+                config->num_bytes > TX_BUFFER_SIZE)
+              {
+                fprintf(stderr,
+                        "Error: Invalid number of bytes for write mode.\n");
+                return -1;
+              }
+
+            break;
+
+          case 't':
+            config->timeout_seconds = atoi(optarg);
+            if (config->timeout_seconds <= 0)
+              {
+                fprintf(stderr,
+                        "Error: Timeout must be a positive integer.\n");
+                return -1;
+              }
+            break;
+
+          case 'l':
+            if (config->mode != MODE_INVALID)
+              {
+                fprintf(stderr,
+                        "Error: Multiple operation modes specified.\n");
+                return -1;
+              }
+
+            config->mode = MODE_LISTEN;
+            break;
+
+          case 'e':
+            if (config->mode != MODE_INVALID)
+              {
+                fprintf(stderr,
+                        "Error: Multiple operation modes specified.\n");
+                return -1;
+              }
+
+            config->mode = MODE_ECHO;
+            break;
+
+          default:
+            fprintf(stderr, "Usage:\n");
+            fprintf(stderr,
+        "  %s -x <num_bytes> [-t <timeout_seconds>] <hex_bytes>\n",
+                    argv[0]);
+            fprintf(stderr,
+                    "  %s -l [-t <timeout_seconds>]\n", argv[0]);
+            fprintf(stderr,
+                    "  %s -e [-t <timeout_seconds>]\n", argv[0]);
+            printf("Examples:\n");
+            printf("  spislv -x 2 abba\n");
+            printf("  spislv -l -t 5\n");
+            printf("  spislv -e -t 10\n\n");
+            return -1;
+        }
+    }
+
+  /* Validate mutual exclusivity and required arguments */
+
+  if (config->mode == MODE_WRITE)
+    {
+      if (optind >= argc)
+        {
+          fprintf(stderr,
+                  "Error: Missing hexadecimal bytes to send.\n");
+          fprintf(stderr,
+        "Usage: %s -x <num_bytes> [-t <timeout_seconds>] <hex_bytes>\n",
+                  argv[0]);
+          return -1;
+        }
+
+      char *hex_input = argv[optind];
+
+      /* Verify the hexadecimal string length */
+
+      if (strlen(hex_input) != (size_t)(config->num_bytes * 2))
         {
-          buffer[bytes_read] = '\0';
+          fprintf(stderr,
+                  "Error: Hex string length must be %d characters\n"
+                  "for %d bytes.\n",
+                  config->num_bytes * 2, config->num_bytes);
+          return -1;
+        }
+
+      /* Convert hexadecimal string to byte array */
+
+      int converted = hexstr_to_bytes(hex_input, config->tx_buffer,
+                                      TX_BUFFER_SIZE);
+      if (converted != config->num_bytes)
+        {
+          fprintf(stderr, "Error: Invalid hexadecimal string.\n");
+          return -1;
+        }
+    }
+
+  else if (config->mode == MODE_INVALID)
+    {
+      fprintf(stderr, "Error: No operation mode specified.\n");
+      fprintf(stderr, "Usage:\n");
+      fprintf(stderr,
+        "  %s -x <num_bytes> [-t <timeout_seconds>] <hex_bytes>\n",
+              argv[0]);
+      fprintf(stderr,
+              "  %s -l [-t <timeout_seconds>]\n", argv[0]);
+      fprintf(stderr,
+              "  %s -e [-t <timeout_seconds>]\n", argv[0]);
+      printf("Examples:\n");
+      printf("  spislv -x 2 abba\n");
+      printf("  spislv -l -t 5\n");
+      printf("  spislv -e -t 10\n");
+      return -1;
+    }
+
+  return 0;
+}
+
+/**
+ * @brief Executes the write mode: sends specified bytes to the master.
+ *
+ * @param config Pointer to the program configuration structure.
+ * @param fd File descriptor for the SPI device.
+ * @return 0 on success, -1 on failure.
+ */
+
+static int write_mode(program_config_t *config, int fd)
+{
+  ssize_t bytes_written;
+  char data_str[3 * TX_BUFFER_SIZE + 1]; /* Buffer for debug string */
+  char *ptr = data_str;
+
+  for (int i = 0; i < config->num_bytes; i++)
+    {
+      int len = snprintf(ptr,
+                         sizeof(data_str) - (ptr - data_str),
+                         "%02X ",
+                         config->tx_buffer[i]);

Review Comment:
   Ok, I will.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscr...@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
us...@infra.apache.org

Reply via email to