Fix some register's values, enable TWAI extended registers and add a missing prototype.

Also, replaced critical_sections with spinlocks.
This commit is contained in:
Victor Benso 2022-09-02 18:48:28 -03:00 committed by Xiang Xiao
parent 85c8144afa
commit 2892f18f15
3 changed files with 65 additions and 39 deletions

View File

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

View File

@ -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 */

View File

@ -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 */