You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by xi...@apache.org on 2022/09/09 07:30:41 UTC

[incubator-nuttx] branch master updated: Fix some register's values, enable TWAI extended registers and add a missing prototype. Also, replaced critical_sections with spinlocks.

This is an automated email from the ASF dual-hosted git repository.

xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git


The following commit(s) were added to refs/heads/master by this push:
     new 2892f18f15 Fix some register's values, enable TWAI extended registers and add a missing prototype. Also, replaced critical_sections with spinlocks.
2892f18f15 is described below

commit 2892f18f15a6581066d9564e77f98885ddaed1e8
Author: Victor Benso <vb...@gmail.com>
AuthorDate: Fri Sep 2 18:48:28 2022 -0300

    Fix some register's values, enable TWAI extended registers and add a missing prototype.
    Also, replaced critical_sections with spinlocks.
---
 arch/xtensa/src/esp32/esp32_twai.c                 | 71 ++++++++++++----------
 arch/xtensa/src/esp32/hardware/esp32_twai.h        | 22 +++++--
 .../xtensa/esp32/esp32-devkitc/src/esp32-devkitc.h | 11 ++++
 3 files changed, 65 insertions(+), 39 deletions(-)

diff --git a/arch/xtensa/src/esp32/esp32_twai.c b/arch/xtensa/src/esp32/esp32_twai.c
index ac6c5905db..59ba6f161e 100644
--- a/arch/xtensa/src/esp32/esp32_twai.c
+++ b/arch/xtensa/src/esp32/esp32_twai.c
@@ -37,6 +37,7 @@
 #include <nuttx/irq.h>
 #include <nuttx/arch.h>
 #include <nuttx/can/can.h>
+#include <nuttx/spinlock.h>
 
 #include "xtensa.h"
 
@@ -124,15 +125,16 @@ struct twai_dev_s
   /* Device configuration */
 
   const struct can_bittiming_const *bittiming_const;
-  uint8_t port;       /* TWAI port number */
-  uint8_t periph;     /* Peripheral ID */
-  uint8_t irq;        /* IRQ associated with this TWAI */
-  uint8_t cpu;        /* CPU ID */
-  uint8_t cpuint;     /* CPU interrupt assigned to this TWAI */
-  uint32_t bitrate;   /* Configured bit rate */
-  uint32_t samplep;   /* Configured sample point */
-  uint32_t sjw;       /* Synchronization jump width */
-  uint32_t base;      /* TWAI register base address */
+  uint8_t    port;       /* TWAI port number */
+  uint8_t    periph;     /* Peripheral ID */
+  uint8_t    irq;        /* IRQ associated with this TWAI */
+  uint8_t    cpu;        /* CPU ID */
+  uint8_t    cpuint;     /* CPU interrupt assigned to this TWAI */
+  uint32_t   bitrate;    /* Configured bit rate */
+  uint32_t   samplep;    /* Configured sample point */
+  uint32_t   sjw;        /* Synchronization jump width */
+  uint32_t   base;       /* TWAI register base address */
+  spinlock_t lock;       /* Device specific lock */
 };
 
 /****************************************************************************
@@ -221,6 +223,7 @@ static struct twai_dev_s g_twai0priv =
   .samplep          = CONFIG_ESP32_TWAI0_SAMPLEP,
   .sjw              = CONFIG_ESP32_TWAI0_SJW,
   .base             = DR_REG_TWAI_BASE,
+  .lock             = SP_UNLOCKED,
 };
 
 static struct can_dev_s g_twai0dev =
@@ -386,13 +389,15 @@ static void esp32twai_reset(struct can_dev_s *dev)
 
   caninfo("TWAI%" PRIu8 "\n", priv->port);
 
-  flags = enter_critical_section();
+  flags = spin_lock_irqsave(&priv->lock);
 
   /* Disable the TWAI and stop ongoing transmissions */
 
   uint32_t mode_value = TWAI_RESET_MODE_M | TWAI_LISTEN_ONLY_MODE_M;
   twai_putreg(TWAI_MODE_REG, mode_value);                 /* Enter Reset Mode */
 
+  modifyreg32(TWAI_CLOCK_DIVIDER_REG, 0, TWAI_EXT_MODE_M);
+
   twai_putreg(TWAI_INT_ENA_REG, 0);                       /* Disable interrupts */
   twai_getreg(TWAI_STATUS_REG);                           /* Clear status bits */
 
@@ -427,8 +432,7 @@ static void esp32twai_reset(struct can_dev_s *dev)
 
   twai_putreg(TWAI_CMD_REG, TWAI_ABORT_TX_M | TWAI_RELEASE_BUF_M |
               TWAI_CLR_OVERRUN_M);
-
-  leave_critical_section(flags);
+  spin_unlock_irqrestore(&priv->lock, flags);
 }
 
 /****************************************************************************
@@ -455,7 +459,7 @@ static int esp32twai_setup(struct can_dev_s *dev)
 
   caninfo("TWAI%" PRIu8 "\n", priv->port);
 
-  flags = enter_critical_section();
+  flags = spin_lock_irqsave(&priv->lock);
 
   twai_putreg(TWAI_INT_ENA_REG, TWAI_DEFAULT_INTERRUPTS);
 
@@ -465,7 +469,7 @@ static int esp32twai_setup(struct can_dev_s *dev)
     {
       /* Disable the provided CPU Interrupt to configure it. */
 
-      up_disable_irq(priv->cpuint);
+      up_disable_irq(priv->irq);
     }
 
   priv->cpu = up_cpu_index();
@@ -476,7 +480,7 @@ static int esp32twai_setup(struct can_dev_s *dev)
       /* Failed to allocate a CPU interrupt of this type. */
 
       ret = priv->cpuint;
-      leave_critical_section(flags);
+      spin_unlock_irqrestore(&priv->lock, flags);
 
       return ret;
     }
@@ -488,16 +492,16 @@ static int esp32twai_setup(struct can_dev_s *dev)
 
       esp32_teardown_irq(priv->cpu, priv->periph, priv->cpuint);
       priv->cpuint = -ENOMEM;
-      leave_critical_section(flags);
+      spin_unlock_irqrestore(&priv->lock, flags);
 
       return ret;
     }
 
   /* Enable the CPU interrupt that is linked to the TWAI device. */
 
-  up_enable_irq(priv->cpuint);
+  up_enable_irq(priv->irq);
 
-  leave_critical_section(flags);
+  spin_unlock_irqrestore(&priv->lock, flags);
 
   return ret;
 }
@@ -529,7 +533,7 @@ static void esp32twai_shutdown(struct can_dev_s *dev)
     {
       /* Disable cpu interrupt */
 
-      up_disable_irq(priv->cpuint);
+      up_disable_irq(priv->irq);
 
       /* Dissociate the IRQ from the ISR */
 
@@ -571,7 +575,8 @@ static void esp32twai_rxint(struct can_dev_s *dev, bool enable)
    * so we have to protect this code section.
    */
 
-  flags = enter_critical_section();
+  flags = spin_lock_irqsave(&priv->lock);
+
   regval = twai_getreg(TWAI_INT_ENA_REG);
   if (enable)
     {
@@ -583,7 +588,8 @@ static void esp32twai_rxint(struct can_dev_s *dev, bool enable)
     }
 
   twai_putreg(TWAI_INT_ENA_REG, regval);
-  leave_critical_section(flags);
+  spin_unlock_irqrestore(&priv->lock, flags);
+
   return;
 }
 
@@ -621,14 +627,14 @@ static void esp32twai_txint(struct can_dev_s *dev, bool enable)
        * have to protect this code section.
        */
 
-      flags = enter_critical_section();
+      flags = spin_lock_irqsave(&priv->lock);
 
       /* Disable all TX interrupts */
 
       regval = twai_getreg(TWAI_INT_ENA_REG);
       regval &= ~(TWAI_TX_INT_ENA_M);
       twai_putreg(TWAI_INT_ENA_REG, regval);
-      leave_critical_section(flags);
+      spin_unlock_irqrestore(&priv->lock, flags);
     }
 }
 
@@ -764,7 +770,7 @@ static int esp32twai_send(struct can_dev_s *dev,
       frame_info |= (1 << 6);
     }
 
-  flags = enter_critical_section();
+  flags = spin_lock_irqsave(&priv->lock);
 
   /* Make sure that TX interrupts are enabled BEFORE sending the
    * message.
@@ -826,8 +832,7 @@ static int esp32twai_send(struct can_dev_s *dev,
 #else
     twai_putreg(TWAI_CMD_REG, TWAI_TX_REQ_M);
 #endif
-
-  leave_critical_section(flags);
+  spin_unlock_irqrestore(&priv->lock, flags);
 
   return ret;
 }
@@ -1170,7 +1175,7 @@ static int twai_baud_rate(struct twai_dev_s *priv, int rate, int clock,
 
   /* Configure bit timing */
 
-  timing0 = (best_brp - 1) / 2;
+  timing0 = (best_brp / 2) - 1;
   timing0 |= (sjw - 1) << TWAI_SYNC_JUMP_WIDTH_S;
 
   timing1 = tseg1 - 1;
@@ -1215,11 +1220,13 @@ struct can_dev_s *esp32_twaiinitialize(int port)
 
   caninfo("TWAI%" PRIu8 "\n",  port);
 
-  flags = enter_critical_section();
-
 #ifdef CONFIG_ESP32_TWAI0
   if (port == 0)
     {
+      twaidev = &g_twai0dev;
+
+      flags = spin_lock_irqsave(&g_twai0priv.lock);
+
       /* Enable power to the TWAI module and
        * Enable clocking to the TWAI module
        */
@@ -1235,14 +1242,14 @@ struct can_dev_s *esp32_twaiinitialize(int port)
       esp32_configgpio(CONFIG_ESP32_TWAI0_RXPIN, INPUT_FUNCTION_1);
       esp32_gpio_matrix_in(CONFIG_ESP32_TWAI0_RXPIN, TWAI_RX_IDX, 0);
 
-      twaidev = &g_twai0dev;
+      spin_unlock_irqrestore(&g_twai0priv.lock, flags);
     }
   else
 #endif
 
     {
       canerr("ERROR: Unsupported port: %d\n", port);
-      leave_critical_section(flags);
+
       return NULL;
     }
 
@@ -1250,8 +1257,6 @@ struct can_dev_s *esp32_twaiinitialize(int port)
 
   esp32twai_reset(twaidev);
 
-  leave_critical_section(flags);
-
   return twaidev;
 }
 #endif
diff --git a/arch/xtensa/src/esp32/hardware/esp32_twai.h b/arch/xtensa/src/esp32/hardware/esp32_twai.h
index c9811826e6..26b96e8e52 100644
--- a/arch/xtensa/src/esp32/hardware/esp32_twai.h
+++ b/arch/xtensa/src/esp32/hardware/esp32_twai.h
@@ -383,7 +383,7 @@
 #define TWAI_SYNC_JUMP_WIDTH    0x00000003
 #define TWAI_SYNC_JUMP_WIDTH_M  (TWAI_SYNC_JUMP_WIDTH_V << TWAI_SYNC_JUMP_WIDTH_S)
 #define TWAI_SYNC_JUMP_WIDTH_V  0x00000003
-#define TWAI_SYNC_JUMP_WIDTH_S  14
+#define TWAI_SYNC_JUMP_WIDTH_S  6
 
 /* TWAI_BAUD_PRESC : RO | R/W; bitpos: [13:0]; default: 0;
  * Baud Rate Prescaler, determines the frequency dividing ratio.
@@ -833,24 +833,34 @@
 
 #define TWAI_CLOCK_DIVIDER_REG (DR_REG_TWAI_BASE + 0x7c)
 
-/* TWAI_CLOCK_OFF : RO | R/W; bitpos: [8]; default: 0;
+/* TWAI_CLOCK_OFF : RO | R/W; bitpos: [3]; default: 0;
  * This bit can be configured under reset mode. 1: Disable the external
  * CLKOUT pin; 0: Enable the external CLKOUT pin
  */
 
-#define TWAI_CLOCK_OFF    (BIT(8))
+#define TWAI_CLOCK_OFF    (BIT(3))
 #define TWAI_CLOCK_OFF_M  (TWAI_CLOCK_OFF_V << TWAI_CLOCK_OFF_S)
 #define TWAI_CLOCK_OFF_V  0x00000001
-#define TWAI_CLOCK_OFF_S  8
+#define TWAI_CLOCK_OFF_S  3
+
+/* TWAI_EXT_MODE : RO | R/W; bitpos: [7]; default: 0;
+ * This bit can be configured under reset mode. 1: Extended mode, compatible
+ * with CAN2.0B; 0: Basic mode
+ */
+
+#define TWAI_EXT_MODE    (BIT(7))
+#define TWAI_EXT_MODE_M  (TWAI_EXT_MODE_V << TWAI_EXT_MODE_S)
+#define TWAI_EXT_MODE_V  0x00000001
+#define TWAI_EXT_MODE_S  7
 
 /* TWAI_CD : R/W; bitpos: [7:0]; default: 0;
  * These bits are used to configure frequency dividing coefficients of the
  * external CLKOUT pin.
  */
 
-#define TWAI_CD    0x000000FF
+#define TWAI_CD    0x00000007
 #define TWAI_CD_M  (TWAI_CD_V << TWAI_CD_S)
-#define TWAI_CD_V  0x000000FF
+#define TWAI_CD_V  0x00000007
 #define TWAI_CD_S  0
 
 #endif /* __ARCH_XTENSA_SRC_ESP32_HARDWARE_ESP32_TWAI_H */
diff --git a/boards/xtensa/esp32/esp32-devkitc/src/esp32-devkitc.h b/boards/xtensa/esp32/esp32-devkitc/src/esp32-devkitc.h
index 2640f5a01d..b919197eae 100644
--- a/boards/xtensa/esp32/esp32-devkitc/src/esp32-devkitc.h
+++ b/boards/xtensa/esp32/esp32-devkitc/src/esp32-devkitc.h
@@ -140,5 +140,16 @@ int esp32_pwm_setup(void);
 int board_spidev_initialize(int bus);
 #endif
 
+/****************************************************************************
+ * Name: esp32_twai_setup
+ *
+ * Description:
+ *  Initialize TWAI and register the TWAI device
+ *
+ ****************************************************************************/
+#ifdef CONFIG_ESP32_TWAI
+int esp32_twai_setup(void);
+#endif
+
 #endif /* __ASSEMBLY__ */
 #endif /* __BOARDS_XTENSA_ESP32_ESP32_DEVKITC_SRC_ESP32_DEVKITC_H */