You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by GitBox <gi...@apache.org> on 2021/04/28 16:46:52 UTC

[GitHub] [incubator-nuttx] gustavonihei commented on a change in pull request #3543: feat(esp32c3): Support esp32c3 ble function

gustavonihei commented on a change in pull request #3543:
URL: https://github.com/apache/incubator-nuttx/pull/3543#discussion_r622361348



##########
File path: arch/risc-v/src/esp32c3/esp32c3_ttyhci.c
##########
@@ -0,0 +1,529 @@
+/****************************************************************************
+ * arch/risc-v/src/esp32c3/esp32c3_ttyhci.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#include <nuttx/fs/fs.h>
+#include <nuttx/kmalloc.h>
+#include <nuttx/semaphore.h>
+#include <nuttx/nuttx.h>
+#include <nuttx/serial/serial.h>
+#include <nuttx/kthread.h>
+
+#include <string.h>
+#include <stdio.h>
+#include <poll.h>
+#include <queue.h>
+
+#include <nuttx/wireless/bluetooth/bt_uart.h>
+#include <nuttx/wireless/bluetooth/bt_hci.h>
+
+#include "esp32c3_ttyhci.h"
+#include "esp32c3_hcisocket_host.h"
+#include "esp32c3_ble_adapter.h"
+
+#include <time.h>
+#include <sys/time.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define CONFIG_HCI_RXBUFSIZE    1024
+#define CONFIG_HCI_TXBUFSIZE    1024
+#define CONFIG_HCI_NPOLLWAITERS    2
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+begin_packed_struct struct bt_hci_evt_hdr_s
+{
+  uint8_t evt;
+  uint8_t len;
+} end_packed_struct;
+
+begin_packed_struct struct bt_hci_acl_hdr_s
+{
+  uint16_t handle          : 12;
+  uint16_t packet_boundary : 2;
+  uint16_t broadcast       : 2;
+  uint16_t len;
+} end_packed_struct;
+
+begin_packed_struct struct bt_hci_iso_hdr_s
+{
+  uint16_t handle;
+  uint16_t len;
+} end_packed_struct;
+
+begin_packed_struct struct bt_hci_cmd_hdr_s
+{
+  uint16_t opcode;
+  uint8_t param_len;
+} end_packed_struct;
+
+union bt_hdr_u
+{
+  struct bt_hci_cmd_hdr_s cmd;
+  struct bt_hci_acl_hdr_s acl;
+  struct bt_hci_evt_hdr_s evt;
+  struct bt_hci_iso_hdr_s iso;
+};
+
+struct bthcitty_s
+{
+  sq_entry_t              link;
+  uint8_t                 recvbuf[CONFIG_HCI_RXBUFSIZE];
+  size_t                  recvpos;
+  size_t                  recvlen;
+  sem_t                   recvsem;
+  sem_t                   recvlock;
+  uint8_t                 sendbuf[CONFIG_HCI_TXBUFSIZE];
+  size_t                  sendlen;
+  sem_t                   sendlock;
+  sem_t                   fdslock;
+  FAR struct pollfd       *fds[CONFIG_HCI_NPOLLWAITERS];
+  unsigned short          id;
+  int                     fd;
+};
+
+struct host_hci_t
+{
+  bool send_avail;
+  struct uart_dev_s *dev ;
+};
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static int  esp_bt_tty_setup(struct uart_dev_s *dev);
+static void esp_bt_tty_shutdown(struct uart_dev_s *dev);
+static int  esp_bt_tty_attach(struct uart_dev_s *dev);
+static void esp_bt_tty_detach(struct uart_dev_s *dev);
+static void esp_bt_tty_txint(struct uart_dev_s *dev, bool enable);
+static void esp_bt_tty_rxint(struct uart_dev_s *dev, bool enable);
+static bool esp_bt_tty_rxavailable(struct uart_dev_s *dev);
+static bool esp_bt_tty_txready(struct uart_dev_s *dev);
+static bool esp_bt_tty_txempty(struct uart_dev_s *dev);
+static void esp_bt_tty_send(struct uart_dev_s *dev, int ch);
+static int  esp_bt_tty_receive(struct uart_dev_s *dev, unsigned int *status);
+static int  esp_bt_tty_ioctl(struct file *filep, int cmd, unsigned long arg);
+static void esp_bt_send_task(void *pvparameters);
+
+/****************************************************************************
+ * Public Functions declaration
+ ****************************************************************************/
+
+int bthcitty_register(int dev_id);
+int esp_bt_initialize(void);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static char g_hci_rxbuffer[CONFIG_HCI_RXBUFSIZE];
+static char g_hci_txbuffer[CONFIG_HCI_TXBUFSIZE];
+static char g_host_recv_buffer[1024];
+static uint32_t g_recv_buffer_len = 0;
+static uint32_t g_recv_buffer_offset = 0;
+
+static struct uart_ops_s g_uart_ops =
+{
+    .setup       = esp_bt_tty_setup,
+    .shutdown    = esp_bt_tty_shutdown,
+    .attach      = esp_bt_tty_attach,
+    .detach      = esp_bt_tty_detach,
+    .txint       = esp_bt_tty_txint,
+    .rxint       = esp_bt_tty_rxint,
+    .rxavailable = esp_bt_tty_rxavailable,
+    .txready     = esp_bt_tty_txready,
+    .txempty     = esp_bt_tty_txempty,
+    .send        = esp_bt_tty_send,
+    .receive     = esp_bt_tty_receive,
+    .ioctl       = esp_bt_tty_ioctl,
+};
+
+static uart_dev_t bt_tty_dev =
+{
+    .isconsole = false,
+    .xmit =
+    {
+        .size   = CONFIG_HCI_TXBUFSIZE,
+        .buffer = g_hci_txbuffer,
+    },
+    .recv =
+    {
+        .size   = CONFIG_HCI_RXBUFSIZE,
+        .buffer = g_hci_rxbuffer,
+    },
+
+    .ops = &g_uart_ops,
+    .priv = NULL
+};
+
+static struct host_hci_t esp_bt_hci_dev =
+{
+  .send_avail = false,
+  .dev = NULL
+};
+
+/****************************************************************************
+ * Public Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions and Public Functions only used by librariestest_dev
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: esp_bt_tty_setup
+ *
+ * Description:
+ *      Configure the UART baud, bits, parity, fifos, etc. This method is
+ *      called the first time that the serial port is opened.
+ *      For the serial console, this will occur very early in initialization,
+ *      for other serial ports this will occur when the port is first opened.
+ *      This setup does not include attaching or enabling interrupts.
+ *      That portion of the UART setup is performed when the attach() method
+ *      is called.
+ *
+ ****************************************************************************/
+
+static int esp_bt_tty_setup(struct uart_dev_s *dev)
+{
+  bthcisock_host_open(0);
+  kthread_create("bt_send_task", 100, 4096, (main_t)esp_bt_send_task, NULL);
+  return OK;
+}
+
+/****************************************************************************
+ * Name: esp_bt_tty_shutdown
+ *
+ * Description:
+ * Disable the UART.  This method is called when the serial port is closed.
+ * This method reverses the operation the setup method.  NOTE that the serial
+ * console is never shutdown.
+ *
+ ****************************************************************************/
+
+static void esp_bt_tty_shutdown(struct uart_dev_s *dev)
+{
+  bthcisock_host_close(0);
+}
+
+/****************************************************************************
+ * Name: esp_bt_tty_attach
+ *
+ * Description:
+ *   Configure the UART to operation in interrupt driven mode.  This method
+ *   is called when the serial port is opened.  Normally, this is just after
+ *   the the setup() method is called, however, the serial console may
+ *   operate in a non-interrupt driven mode during the boot phase.
+ *
+ *   RX and TX interrupts are not enabled when by the attach method (unless
+ *   the hardware supports multiple levels of interrupt enabling).  The RX
+ *   and TX interrupts are not enabled until the txint() and rxint() methods
+ *   are called.
+ *
+ ****************************************************************************/
+
+static int esp_bt_tty_attach(struct uart_dev_s *dev)
+{
+  return OK;
+}
+
+/****************************************************************************
+ * Name: esp_bt_tty_detach
+ *
+ * Description:
+ *   Detach UART interrupts.  This method is called when the serial port is
+ *   closed normally just before the shutdown method is called.  The
+ *   exception is the serial console which is never shutdown.
+ *
+ ****************************************************************************/
+
+static void esp_bt_tty_detach(struct uart_dev_s *dev)
+{
+}
+
+/****************************************************************************
+ * Name: esp_bt_tty_txint
+ *
+ * Description:
+ * Call to enable or disable TX interrupts
+ *
+ ****************************************************************************/
+
+static void esp_bt_tty_txint(struct uart_dev_s *dev, bool enable)
+{
+  if (dev->xmit.head > dev->xmit.tail)
+  {
+    if (enable)
+    {
+      bthcisock_host_send(0, dev->xmit.buffer + dev->xmit.tail,
+                      dev->xmit.head  - dev->xmit.tail);
+      dev->xmit.head = 0;
+      dev->xmit.tail = 0;
+    }
+  }
+}
+
+/****************************************************************************
+ * Name: esp_bt_tty_rxint
+ *
+ * Description:
+ *   Call to enable or disable RXRDY interrupts
+ *
+ ****************************************************************************/
+
+static void esp_bt_tty_rxint(struct uart_dev_s *dev, bool enable)
+{
+  if (enable)
+    {
+      esp_bt_hci_dev.send_avail = true;
+      esp_bt_hci_dev.dev = dev;
+    }
+  else
+    {
+      esp_bt_hci_dev.send_avail = false;
+    }
+}
+
+/****************************************************************************
+ * Name: esp_bt_tty_rxavailable
+ *
+ * Description:
+ *   Return true if the receive holding register is not empty
+ *
+ ****************************************************************************/
+
+static bool esp_bt_tty_rxavailable(struct uart_dev_s *dev)
+{
+  if (g_recv_buffer_offset < g_recv_buffer_len)
+    {
+      return true;
+    }
+  else
+    {
+      g_recv_buffer_offset = 0;
+      g_recv_buffer_len = 0;
+      memset(g_host_recv_buffer, 0x0, 1024);
+      return false;
+    }
+}
+
+/****************************************************************************
+ * Name: esp_bt_tty_txready
+ *
+ * Description:
+ * Return true if the tranmsit hardware is ready to send another byte.  This
+ * is used to determine if send() method can be called.
+ *
+ ****************************************************************************/
+
+static bool esp_bt_tty_txready(struct uart_dev_s *dev)
+{
+  if (esp_vhci_host_check_send_available())
+    {
+      return true;
+    }
+  else
+    {
+      return false;
+    }
+}
+
+/****************************************************************************
+ * Name: esp_bt_tty_txempty
+ *
+ * Description:
+ * Return true if all characters have been sent.  If for example, the UART
+ * hardware implements FIFOs, then this would mean the transmit FIFO is
+ * empty.  This method is called when the driver needs to make sure that
+ * all characters are "drained" from the TX hardware.
+ *
+ ****************************************************************************/
+
+static bool esp_bt_tty_txempty(struct uart_dev_s *dev)
+{
+  return true ;
+}
+
+/****************************************************************************
+ * Name: esp_bt_tty_send
+ *
+ * Description:
+ *
+ ****************************************************************************/
+
+static void esp_bt_tty_send(struct uart_dev_s *dev, int ch)
+{
+  /* Then send the character */
+}
+
+/****************************************************************************
+ * Name: esp_bt_send_task
+ *
+ * Description:
+ * Send the data received from controller to host
+ *
+ ****************************************************************************/
+
+static void esp_bt_send_task(void *pvparameters)
+{
+  uint8_t recv_controller_buf[CONFIG_HCI_RXBUFSIZE];
+  int32_t recv_len = 0;
+  struct uart_dev_s  *dev  = esp_bt_hci_dev.dev;
+
+  while (1)
+    {
+      usleep(10);

Review comment:
       ```suggestion
         nxsig_usleep(10);
   ```
   `usleep` should be avoided in kernel code since it modifies the `errno` and sets cancellation points.




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

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