esp32[c3|h2|c6]: Add support to TWAI/CANBus controller

This commit is contained in:
Eren Terzioglu 2024-04-02 18:49:57 +03:00 committed by Xiang Xiao
parent 7e30d38558
commit 891d67bb5e
32 changed files with 1786 additions and 2 deletions

View File

@ -175,6 +175,25 @@ To test it, just run the following::
Where x in the timer instance.
twai
----
This configuration enables the support for the TWAI (Two-Wire Automotive Interface) driver.
You can test it by connecting TWAI RX and TWAI TX pins which are GPIO0 and GPIO2 by default
to an external transceiver or connecting TWAI RX to TWAI TX pin by enabling
the `CONFIG_CAN_LOOPBACK` option (``Device Drivers -> CAN Driver Support -> CAN loopback mode``)
and running the ``can`` example::
nsh> can
nmsgs: 0
min ID: 1 max ID: 2047
Bit timing:
Baud: 1000000
TSEG1: 15
TSEG2: 4
SJW: 3
ID: 1 DLC: 1
usbconsole
----------

View File

@ -148,6 +148,7 @@ Peripheral Support NOTES
ADC No
AES No
Bluetooth No
CAN/TWAI Yes
CDC Console Yes Rev.3
DMA No
eFuse No

View File

@ -210,6 +210,25 @@ To test it, just run the following::
Where x in the timer instance.
twai
----
This configuration enables the support for the TWAI (Two-Wire Automotive Interface) driver.
You can test it by connecting TWAI RX and TWAI TX pins which are GPIO0 and GPIO2 by default
to an external transceiver or connecting TWAI RX to TWAI TX pin by enabling
the `CONFIG_CAN_LOOPBACK` option (``Device Drivers -> CAN Driver Support -> CAN loopback mode``)
and running the ``can`` example::
nsh> can
nmsgs: 0
min ID: 1 max ID: 2047
Bit timing:
Baud: 1000000
TSEG1: 15
TSEG2: 4
SJW: 3
ID: 1 DLC: 1
usbconsole
----------

View File

@ -210,6 +210,25 @@ To test it, just run the following::
Where x in the timer instance.
twai
----
This configuration enables the support for the TWAI (Two-Wire Automotive Interface) driver.
You can test it by connecting TWAI RX and TWAI TX pins which are GPIO0 and GPIO2 by default
to an external transceiver or connecting TWAI RX to TWAI TX pin by enabling
the `CONFIG_CAN_LOOPBACK` option (``Device Drivers -> CAN Driver Support -> CAN loopback mode``)
and running the ``can`` example::
nsh> can
nmsgs: 0
min ID: 1 max ID: 2047
Bit timing:
Baud: 1000000
TSEG1: 15
TSEG2: 4
SJW: 3
ID: 1 DLC: 1
usbconsole
----------

View File

@ -138,7 +138,7 @@ Peripheral Support
ADC No
AES No
Bluetooth No
CAN/TWAI No
CAN/TWAI Yes
DMA No
ECC No
eFuse No

View File

@ -209,6 +209,25 @@ To test it, just run the following::
Where x in the timer instance.
twai
----
This configuration enables the support for the TWAI (Two-Wire Automotive Interface) driver.
You can test it by connecting TWAI RX and TWAI TX pins which are GPIO0 and GPIO2 by default
to an external transceiver or connecting TWAI RX to TWAI TX pin by enabling
the `CONFIG_CAN_LOOPBACK` option (``Device Drivers -> CAN Driver Support -> CAN loopback mode``)
and running the ``can`` example::
nsh> can
nmsgs: 0
min ID: 1 max ID: 2047
Bit timing:
Baud: 1000000
TSEG1: 15
TSEG2: 4
SJW: 3
ID: 1 DLC: 1
usbconsole
----------

View File

@ -138,7 +138,7 @@ Peripheral Support
ADC No
AES No
Bluetooth No
CAN/TWAI No
CAN/TWAI Yes
DMA No
ECC No
eFuse No

View File

@ -269,6 +269,27 @@ config ESPRESSIF_UART1
select UART1_SERIALDRIVER
select ARCH_HAVE_SERIAL_TERMIOS
config ESPRESSIF_TWAI
bool "TWAI (CAN)"
default n
select ARCH_HAVE_CAN_ERRORS
select CAN
config ESPRESSIF_TWAI0
bool "TWAI0 (CAN)"
default n
select ESPRESSIF_TWAI
select ARCH_HAVE_CAN_ERRORS
select CAN
config ESPRESSIF_TWAI1
bool "TWAI1 (CAN)"
default n
depends on ESPRESSIF_ESP32C6
select ESPRESSIF_TWAI
select ARCH_HAVE_CAN_ERRORS
select CAN
config ESPRESSIF_USBSERIAL
bool "USB-Serial-JTAG Driver"
default n
@ -395,6 +416,104 @@ endif # ESPRESSIF_UART1
endmenu # UART Configuration
menu "TWAI driver options"
depends on ESPRESSIF_TWAI
if ESPRESSIF_TWAI0
config ESPRESSIF_TWAI0_TXPIN
int "TWAI0 TX Pin"
default 2
config ESPRESSIF_TWAI0_RXPIN
int "TWAI0 RX Pin"
default 3
choice ESPRESSIF_TWAI0_TIMING
prompt "TWAI0 Timing config"
default TWAI0_TIMING_100KBITS
---help---
These options control timing of TWAI0.
config TWAI0_TIMING_100KBITS
bool "100 KBits"
config TWAI0_TIMING_125KBITS
bool "125 KBits"
config TWAI0_TIMING_250KBITS
bool "250 KBits"
config TWAI0_TIMING_500KBITS
bool "500 KBits"
config TWAI0_TIMING_800KBITS
bool "800 KBits"
endchoice # ESPRESSIF_TWAI0_TIMING
config ESPRESSIF_TWAI0_SAM
bool "TWAI0 sampling"
default n
---help---
The bus is sampled 3 times (recommended for low to medium speed buses
to spikes on the bus-line).
endif # ESPRESSIF_TWAI0
if ESPRESSIF_TWAI1
config ESPRESSIF_TWAI1_TXPIN
int "TWAI1 TX Pin"
default 4
config ESPRESSIF_TWAI1_RXPIN
int "TWAI1 RX Pin"
default 5
choice ESPRESSIF_TWAI1_TIMING
prompt "TWAI1 Timing config"
default TWAI1_TIMING_100KBITS
---help---
These options control timing of TWAI1.
config TWAI1_TIMING_100KBITS
bool "100 KBits"
config TWAI1_TIMING_125KBITS
bool "125 KBits"
config TWAI1_TIMING_250KBITS
bool "250 KBits"
config TWAI1_TIMING_500KBITS
bool "500 KBits"
config TWAI1_TIMING_800KBITS
bool "800 KBits"
endchoice # ESPRESSIF_TWAI1_TIMING
config ESPRESSIF_TWAI1_SAM
bool "TWAI1 sampling"
default n
---help---
The bus is sampled 3 times (recommended for low to medium speed buses
to spikes on the bus-line).
endif # ESPRESSIF_TWAI1
config ESPRESSIF_TWAI_TEST_MODE
bool "TWAI character driver loopback test mode (for testing only)"
default n
depends on CAN_LOOPBACK
---help---
This enables a loopback test mode that attaches the transmitter
to the receiver internally, being able to test the TWAI
peripheral without any external connection.
endmenu #ESPRESSIF_TWAI
menu "SPI Flash Configuration"
choice ESPRESSIF_FLASH_MODE

View File

@ -65,6 +65,10 @@ ifeq ($(CONFIG_ESPRESSIF_HR_TIMER),y)
CHIP_CSRCS += esp_hr_timer.c
endif
ifeq ($(CONFIG_ESPRESSIF_TWAI),y)
CHIP_CSRCS += esp_twai.c
endif
ifeq ($(CONFIG_ESPRESSIF_LEDC),y)
CHIP_CSRCS += esp_ledc.c
endif

View File

@ -0,0 +1,855 @@
/****************************************************************************
* arch/risc-v/src/common/espressif/esp_twai.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 <stdio.h>
#include <sys/types.h>
#include <inttypes.h>
#include <stdint.h>
#include <stdbool.h>
#include <assert.h>
#include <errno.h>
#include <debug.h>
#include <arch/board/board.h>
#include <nuttx/irq.h>
#include <nuttx/arch.h>
#include <nuttx/spinlock.h>
#include <nuttx/can/can.h>
#include <nuttx/signal.h>
#include "riscv_internal.h"
#include "esp_gpio.h"
#include "esp_twai.h"
#include "esp_irq.h"
#include "esp_clk.h"
#include "periph_ctrl.h"
#include "hal/twai_hal.h"
#include "hal/twai_ll.h"
#include "soc/gpio_sig_map.h"
#include "soc/reg_base.h"
#if defined(CONFIG_ESPRESSIF_TWAI)
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
# if defined(CONFIG_CAN_LOOPBACK) && defined(CONFIG_ESPRESSIF_TWAI_TEST_MODE)
# define TX_PIN_ATTR (OUTPUT_FUNCTION_1 | INPUT_FUNCTION_1)
# define RX_PIN_ATTR (OUTPUT_FUNCTION_1 | INPUT_FUNCTION_1)
# else
# define TX_PIN_ATTR OUTPUT_FUNCTION_1
# define RX_PIN_ATTR INPUT_FUNCTION_1
# endif
# ifdef CONFIG_ESPRESSIF_TWAI0
# ifdef CONFIG_TWAI0_TIMING_100KBITS
#define TWAI0_TIMING_CONFIG TWAI_TIMING_CONFIG_100KBITS()
# elif CONFIG_TWAI0_TIMING_125KBITS
#define TWAI0_TIMING_CONFIG TWAI_TIMING_CONFIG_125KBITS()
# elif CONFIG_TWAI0_TIMING_250KBITS
#define TWAI0_TIMING_CONFIG TWAI_TIMING_CONFIG_250KBITS()
# elif CONFIG_TWAI0_TIMING_500KBITS
#define TWAI0_TIMING_CONFIG TWAI_TIMING_CONFIG_500KBITS()
# else
#define TWAI0_TIMING_CONFIG TWAI_TIMING_CONFIG_800KBITS()
# endif
# endif
# ifdef CONFIG_ESPRESSIF_TWAI1
# ifdef CONFIG_TWAI1_TIMING_100KBITS
#define TWAI1_TIMING_CONFIG TWAI_TIMING_CONFIG_100KBITS()
# elif CONFIG_TWAI1_TIMING_125KBITS
#define TWAI1_TIMING_CONFIG TWAI_TIMING_CONFIG_125KBITS()
# elif CONFIG_TWAI1_TIMING_250KBITS
#define TWAI1_TIMING_CONFIG TWAI_TIMING_CONFIG_250KBITS()
# elif CONFIG_TWAI1_TIMING_500KBITS
#define TWAI1_TIMING_CONFIG TWAI_TIMING_CONFIG_500KBITS()
# else
#define TWAI1_TIMING_CONFIG TWAI_TIMING_CONFIG_800KBITS()
# endif
# endif
# ifdef CONFIG_ESPRESSIF_ESP32C3
# define INT_ENA_REG(hw) hw->interrupt_enable_reg.val
# define PERIPH_TWAI0_MODULE PERIPH_TWAI_MODULE
# define TWAI0_TX_IDX TWAI_TX_IDX
# define TWAI0_RX_IDX TWAI_RX_IDX
# define ETS_TWAI0_INTR_SOURCE ETS_TWAI_INTR_SOURCE
# define ESP_IRQ_TWAI0 ESP_IRQ_TWAI
# else
# define INT_ENA_REG(hw) hw->interrupt_enable.val
# endif /* CONFIG_ESPRESSIF_ESP32C3 */
# ifdef CONFIG_ESPRESSIF_ESP32H2
# define TWAI0_TX_IDX TWAI_TX_IDX
# define TWAI0_RX_IDX TWAI_RX_IDX
# endif /* CONFIG_ESPRESSIF_ESP32H2 */
/* Configuration ************************************************************/
# ifndef CONFIG_CAN_EXTID
# define EXTID 0
# else
# define EXTID 1
# endif
# ifndef CONFIG_CAN_LOOPBACK
# define LOOPBACK 0
# else
# define LOOPBACK 1
# endif
/* Default values written to various registers on initialization */
# define TWAI_DEFAULT_INTERRUPTS 0xe7 /* Exclude data overrun (bit[3]) and brp_div (bit[4]) */
struct esp_twai_dev_s
{
/* Device configuration */
uint8_t port; /* TWAI port number */
uint8_t periph; /* Peripheral ID */
uint8_t irq; /* IRQ associated with this TWAI */
int8_t cpuint; /* CPU interrupt assigned to this TWAI */
twai_hal_context_t ctx; /* Context struct of common layer */
twai_timing_config_t t_config; /* Timing struct of common layer */
};
/****************************************************************************
* Private Function Prototypes
****************************************************************************/
/* TWAI methods */
static void esp_twai_reset(struct can_dev_s *dev);
static int esp_twai_setup(struct can_dev_s *dev);
static void esp_twai_shutdown(struct can_dev_s *dev);
static void esp_twai_rxint(struct can_dev_s *dev, bool enable);
static void esp_twai_txint(struct can_dev_s *dev, bool enable);
static int esp_twai_ioctl(struct can_dev_s *dev, int cmd,
unsigned long arg);
static int esp_twai_remoterequest(struct can_dev_s *dev, uint16_t id);
static int esp_twai_send(struct can_dev_s *dev, struct can_msg_s *msg);
static bool esp_twai_txready(struct can_dev_s *dev);
static bool esp_twai_txempty(struct can_dev_s *dev);
/* TWAI interrupts */
static int esp_twai_interrupt(int irq, void *context, void *arg);
/****************************************************************************
* Private Data
****************************************************************************/
static const struct can_ops_s g_twaiops =
{
.co_reset = esp_twai_reset,
.co_setup = esp_twai_setup,
.co_shutdown = esp_twai_shutdown,
.co_rxint = esp_twai_rxint,
.co_txint = esp_twai_txint,
.co_ioctl = esp_twai_ioctl,
.co_remoterequest = esp_twai_remoterequest,
.co_send = esp_twai_send,
.co_txready = esp_twai_txready,
.co_txempty = esp_twai_txempty,
};
#ifdef CONFIG_ESPRESSIF_TWAI0
static struct esp_twai_dev_s g_twai0priv =
{
.port = 0,
.periph = ETS_TWAI0_INTR_SOURCE,
.irq = ESP_IRQ_TWAI0,
.cpuint = -ENOMEM,
.t_config = TWAI0_TIMING_CONFIG,
};
static struct can_dev_s g_twai0dev =
{
.cd_ops = &g_twaiops,
.cd_priv = &g_twai0priv,
};
#endif /* CONFIG_ESPRESSIF_TWAI0 */
#ifdef CONFIG_ESPRESSIF_TWAI1
static struct esp_twai_dev_s g_twai1priv =
{
.port = 1,
.periph = ETS_TWAI1_INTR_SOURCE,
.irq = ESP_IRQ_TWAI1,
.cpuint = -ENOMEM,
.t_config = TWAI1_TIMING_CONFIG,
};
static struct can_dev_s g_twai1dev =
{
.cd_ops = &g_twaiops,
.cd_priv = &g_twai1priv,
};
#endif /* CONFIG_ESPRESSIF_TWAI1 */
static const twai_filter_config_t f_config = TWAI_FILTER_CONFIG_ACCEPT_ALL();
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: esp_twai_reset
*
* Description:
* Reset the TWAI device. Called early to initialize the hardware. This
* function is called, before esp_twai_setup() and on error conditions.
*
* Input Parameters:
* dev - An instance of the "upper half" CAN driver state structure.
*
* Returned Value:
* None
*
****************************************************************************/
static void esp_twai_reset(struct can_dev_s *dev)
{
struct esp_twai_dev_s *priv = (struct esp_twai_dev_s *)dev->cd_priv;
irqstate_t flags;
int ret;
twai_hal_config_t hal_config =
{
.clock_source_hz = esp_clk_apb_freq(),
.controller_id = priv->port,
};
caninfo("TWAI%" PRIu8 "\n", priv->port);
flags = enter_critical_section();
ret = twai_hal_init(&priv->ctx, &hal_config);
assert(ret);
twai_hal_configure(&priv->ctx, &priv->t_config, &f_config,
TWAI_DEFAULT_INTERRUPTS, 0);
/* Restart the TWAI */
#ifdef CONFIG_CAN_LOOPBACK
twai_hal_start(&priv->ctx, TWAI_MODE_NO_ACK); /* Leave Reset Mode, enter Test Mode */
#else
twai_hal_start(&priv->ctx, TWAI_MODE_NORMAL); /* Leave Reset Mode */
#endif
/* Abort transmission, release RX buffer and clear overrun.
* Command register can only be modified when in Operation Mode.
*/
twai_ll_set_cmd_release_rx_buffer(priv->ctx.dev);
twai_ll_set_cmd_abort_tx(priv->ctx.dev);
twai_ll_set_cmd_clear_data_overrun(priv->ctx.dev);
leave_critical_section(flags);
}
/****************************************************************************
* Name: esp_twai_setup
*
* Description:
* Configure the TWAI. This method is called the first time that the TWAI
* the device is opened and it configures and attaches the TWAI interrupts.
*
* Input Parameters:
* dev - An instance of the "upper half" CAN driver state structure.
*
* Returned Value:
* Zero on success; a negated errno on failure
*
****************************************************************************/
static int esp_twai_setup(struct can_dev_s *dev)
{
struct esp_twai_dev_s *priv = (struct esp_twai_dev_s *)dev->cd_priv;
irqstate_t flags;
int ret = OK;
caninfo("TWAI%" PRIu8 "\n", priv->port);
flags = enter_critical_section();
twai_ll_set_enabled_intrs(priv->ctx.dev, TWAI_DEFAULT_INTERRUPTS);
twai_ll_get_and_clear_intrs(priv->ctx.dev); /* clear latched interrupts */
if (priv->cpuint != -ENOMEM)
{
/* Disable the provided CPU Interrupt to configure it. */
up_disable_irq(priv->irq);
}
priv->cpuint = esp_setup_irq(priv->periph,
ESP_IRQ_PRIORITY_DEFAULT,
ESP_IRQ_TRIGGER_LEVEL);
if (priv->cpuint < 0)
{
/* Failed to allocate a CPU interrupt of this type. */
ret = priv->cpuint;
leave_critical_section(flags);
return ret;
}
ret = irq_attach(priv->irq, esp_twai_interrupt, dev);
if (ret != OK)
{
/* Failed to attach IRQ, so CPU interrupt must be freed. */
esp_teardown_irq(priv->periph, priv->cpuint);
priv->cpuint = -ENOMEM;
leave_critical_section(flags);
return ret;
}
/* Enable the CPU interrupt that is linked to the TWAI device. */
up_enable_irq(priv->irq);
leave_critical_section(flags);
return ret;
}
/****************************************************************************
* Name: esp_twai_shutdown
*
* Description:
* Disable the TWAI. This method is called when the TWAI device is closed.
* This method reverses the operation the setup method.
*
* Input Parameters:
* dev - An instance of the "upper half" CAN driver state structure.
*
* Returned Value:
* None
*
****************************************************************************/
static void esp_twai_shutdown(struct can_dev_s *dev)
{
struct esp_twai_dev_s *priv = (struct esp_twai_dev_s *)dev->cd_priv;
#ifdef CONFIG_DEBUG_CAN_INFO
caninfo("shutdown TWAI%" PRIu8 "\n", priv->port);
#endif
if (priv->cpuint != -ENOMEM)
{
/* Disable cpu interrupt */
up_disable_irq(priv->irq);
/* Dissociate the IRQ from the ISR */
irq_detach(priv->irq);
/* Free cpu interrupt that is attached to this peripheral */
esp_teardown_irq(priv->periph, priv->cpuint);
priv->cpuint = -ENOMEM;
}
}
/****************************************************************************
* Name: esp_twai_rxint
*
* Description:
* Call to enable or disable RX interrupts.
*
* Input Parameters:
* dev - An instance of the "upper half" CAN driver state structure.
* enable - Enable or disable receive interrupt.
*
* Returned Value:
* None
*
****************************************************************************/
static void esp_twai_rxint(struct can_dev_s *dev, bool enable)
{
struct esp_twai_dev_s *priv = (struct esp_twai_dev_s *)dev->cd_priv;
uint32_t regval;
irqstate_t flags;
caninfo("TWAI%" PRIu8 " enable: %d\n", priv->port, enable);
/* The INT_ENA register is also modified from the interrupt handler,
* so we have to protect this code section.
*/
flags = enter_critical_section();
regval = twai_ll_get_and_clear_intrs(priv->ctx.dev);
if (enable == true)
{
regval |= TWAI_LL_INTR_RI;
}
else
{
regval &= ~TWAI_LL_INTR_RI;
}
twai_ll_set_enabled_intrs(priv->ctx.dev, regval);
leave_critical_section(flags);
}
/****************************************************************************
* Name: esp_twai_txint
*
* Description:
* Call to enable or disable TX interrupts.
*
* Input Parameters:
* dev - An instance of the "upper half" CAN driver state structure.
* enable - Enable or disable transmit interrupt.
*
* Returned Value:
* None
*
****************************************************************************/
static void esp_twai_txint(struct can_dev_s *dev, bool enable)
{
struct esp_twai_dev_s *priv = (struct esp_twai_dev_s *)dev->cd_priv;
uint32_t regval;
irqstate_t flags;
caninfo("TWAI%" PRIu8 " enable: %d\n", priv->port, enable);
/* Only disabling of the TX interrupt is supported here. The TX interrupt
* is automatically enabled just before a message is sent in order to avoid
* lost TX interrupts.
*/
if (enable == false)
{
/* TX interrupts are also disabled from the interrupt handler, so we
* have to protect this code section.
*/
flags = enter_critical_section();
/* Disable all TX interrupts */
regval = INT_ENA_REG(priv->ctx.dev);
regval &= ~TWAI_LL_INTR_TI;
twai_ll_set_enabled_intrs(priv->ctx.dev, regval);
leave_critical_section(flags);
}
}
/****************************************************************************
* Name: esp_twai_ioctl
*
* Description:
* All ioctl calls will be routed through this method
*
* Input Parameters:
* dev - An instance of the "upper half" CAN driver state structure.
* cmd - A ioctl command.
* arg - A ioctl argument.
*
* Returned Value:
* Zero on success; a negated errno on failure
*
****************************************************************************/
static int esp_twai_ioctl(struct can_dev_s *dev, int cmd, unsigned long arg)
{
struct esp_twai_dev_s *priv = (struct esp_twai_dev_s *)dev->cd_priv;
int ret = -ENOTTY;
caninfo("TWAI%" PRIu8 " cmd=%04x arg=%lu\n", priv->port, cmd, arg);
/* Handle the command */
switch (cmd)
{
/* CANIOC_GET_BITTIMING:
* Description: Return the current bit timing settings
* Argument: A pointer to a write-able instance of struct
* canioc_bittiming_s in which current bit timing
* values will be returned.
* Returned Value: Zero (OK) is returned on success. Otherwise -1
* (ERROR) is returned with the errno variable set
* to indicate the nature of the error.
* Dependencies: None
*/
case CANIOC_GET_BITTIMING:
{
struct canioc_bittiming_s *bt =
(struct canioc_bittiming_s *)arg;
uint32_t timing0;
uint32_t timing1;
uint32_t brp;
DEBUGASSERT(bt != NULL);
brp = (priv->t_config.brp + 1) * 2;
bt->bt_sjw = priv->t_config.sjw + 1;
bt->bt_tseg1 = priv->t_config.tseg_1 + 1;
bt->bt_tseg2 = priv->t_config.tseg_2 + 1;
bt->bt_baud = esp_clk_apb_freq() /
(brp * (bt->bt_tseg1 + bt->bt_tseg2 + 1));
ret = OK;
}
break;
/* Unsupported/unrecognized command */
default:
canerr("ERROR: Unrecognized command: %04x\n", cmd);
break;
}
return ret;
}
/****************************************************************************
* Name: esp_twai_remoterequest
*
* Description:
* Send a remote request
*
* Input Parameters:
* dev - An instance of the "upper half" can driver state structure.
* id - Requested 11-bit data frame identifier
*
* Returned Value:
* Zero on success; a negated errno on failure
*
****************************************************************************/
static int esp_twai_remoterequest(struct can_dev_s *dev, uint16_t id)
{
canwarn("Remote request not implemented\n");
return -ENOSYS;
}
/****************************************************************************
* Name: esp_twai_send
*
* Description:
* Send one TWAI message.
*
* One TWAI-message consists of a maximum of 10 bytes. A message is
* composed of at least the first 2 bytes (when there are no data bytes).
*
* Byte 0: Bits 0-7: Bits 3-10 of the 11-bit TWAI identifier
* Byte 1: Bits 5-7: Bits 0-2 of the 11-bit TWAI identifier
* Bit 4: Remote Transmission Request (RTR)
* Bits 0-3: Data Length Code (DLC)
* Bytes 2-10: TWAI data
*
* Input Parameters:
* dev - An instance of the "upper half" CAN driver state structure.
* msg - A message to send.
*
* Returned Value:
* Zero on success; a negated errno on failure
*
****************************************************************************/
static int esp_twai_send(struct can_dev_s *dev, struct can_msg_s *msg)
{
struct esp_twai_dev_s *priv = (struct esp_twai_dev_s *)dev->cd_priv;
uint32_t regval;
uint32_t i;
uint32_t len;
uint32_t id;
uint32_t twai_flags;
irqstate_t flags;
int ret = OK;
caninfo("TWAI%" PRIu8 " ID: %" PRIu32 " DLC: %" PRIu8 "\n",
priv->port, (uint32_t)msg->cm_hdr.ch_id, msg->cm_hdr.ch_dlc);
len = (uint32_t)msg->cm_hdr.ch_dlc;
if (len > CAN_MAXDATALEN)
{
len = CAN_MAXDATALEN;
}
flags = enter_critical_section();
/* Make sure that TX interrupts are enabled BEFORE sending the
* message.
*
* NOTE: The INT_ENA is also modified from the interrupt handler, but the
* following is safe because interrupts are disabled here.
*/
regval = INT_ENA_REG(priv->ctx.dev);
regval |= TWAI_LL_INTR_TI;
twai_ll_set_enabled_intrs(priv->ctx.dev, regval);
twai_hal_frame_t tx_frame;
/* Adjustments from NuttX TWAI message struct to common layer TWAI struct */
twai_flags = ((EXTID << TWAI_MSG_FLAG_EXTD) |
(msg->cm_hdr.ch_rtr << TWAI_MSG_FLAG_RTR) |
(LOOPBACK << TWAI_MSG_FLAG_SELF));
/* Set up the transfer */
twai_ll_format_frame_buffer(msg->cm_hdr.ch_id, len,
msg->cm_data, twai_flags, &tx_frame);
twai_ll_set_tx_buffer(priv->ctx.dev, &tx_frame);
/* Send the message */
#ifdef CONFIG_CAN_LOOPBACK
twai_ll_set_cmd_self_rx_request(priv->ctx.dev);
#else
twai_ll_set_cmd_tx(priv->ctx.dev);
#endif
leave_critical_section(flags);
return ret;
}
/****************************************************************************
* Name: esp_twai_txready
*
* Description:
* Return true if the TWAI hardware can accept another TX message.
*
* Input Parameters:
* dev - An instance of the "upper half" CAN driver state structure.
*
* Returned Value:
* True if the TWAI hardware is ready to accept another TX message.
*
****************************************************************************/
static bool esp_twai_txready(struct can_dev_s *dev)
{
struct esp_twai_dev_s *priv = dev->cd_priv;
uint32_t regval = twai_ll_get_status(priv->ctx.dev);
caninfo("TWAI%" PRIu8 " txready: %d\n", priv->port,
((regval & TWAI_LL_STATUS_TBS) != 0));
return ((regval & TWAI_LL_STATUS_TBS) != 0);
}
/****************************************************************************
* Name: esp_twai_txempty
*
* Description:
* Return true if all message have been sent. If for example, the TWAI
* 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 before calling
* co_shutdown().
*
* Input Parameters:
* dev - An instance of the "upper half" CAN driver state structure.
*
* Returned Value:
* True if there are no pending TX transfers in the TWAI hardware.
*
****************************************************************************/
static bool esp_twai_txempty(struct can_dev_s *dev)
{
struct esp_twai_dev_s *priv = dev->cd_priv;
uint32_t regval = twai_ll_get_status(priv->ctx.dev);
caninfo("TWAI%" PRIu8 " txempty: %d\n", priv->port,
((regval & TWAI_LL_STATUS_TBS) != 0));
return ((regval & TWAI_LL_STATUS_TBS) != 0);
}
/****************************************************************************
* Name: esp_twai_interrupt
*
* Description:
* TWAI RX/TX interrupt handler
*
* Input Parameters:
* irq - The IRQ number of the interrupt.
* context - The register state save array at the time of the interrupt.
* arg - The pointer to driver structure.
*
* Returned Value:
* Zero on success; a negated errno on failure
*
****************************************************************************/
static int esp_twai_interrupt(int irq, void *context, void *arg)
{
struct can_dev_s *dev = (struct can_dev_s *)arg;
struct esp_twai_dev_s *priv = dev->cd_priv;
struct can_hdr_s hdr;
uint8_t data[8];
uint32_t regval;
twai_hal_frame_t rx_frame;
uint32_t flags = 0;
uint32_t id;
uint8_t dlc;
/* Read the interrupt register results in clearing bits */
regval = twai_ll_get_and_clear_intrs(priv->ctx.dev);
/* Check for a receive interrupt */
if ((regval & TWAI_LL_INTR_RI) != 0)
{
memset(&hdr, 0, sizeof(hdr));
memset(data, 0, sizeof(data));
twai_ll_get_rx_buffer(priv->ctx.dev, &rx_frame);
/* Release the receive buffer */
twai_ll_set_cmd_release_rx_buffer(priv->ctx.dev);
twai_ll_parse_frame_buffer(&rx_frame, &id, &dlc, data, &flags);
hdr.ch_id = id;
hdr.ch_dlc = dlc;
hdr.ch_rtr = (flags && TWAI_MSG_FLAG_RTR) ? 1 : 0;
can_receive(dev, &hdr, data);
}
/* Check for TX buffer complete */
if ((regval & TWAI_LL_INTR_TI) != 0)
{
/* Disable all further TX buffer interrupts */
esp_twai_txint(dev, false);
/* Indicate that the TX is done and a new TX buffer is available */
can_txdone(dev);
}
return OK;
}
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: esp_twaiinitialize
*
* Description:
* Initialize TWAI peripheral
*
* Input Parameters:
* port - Port number (for hardware that has multiple TWAI interfaces)
*
* Returned Value:
* Valid TWAI device structure reference on success; a NULL on failure
*
****************************************************************************/
struct can_dev_s *esp_twaiinitialize(int port)
{
struct can_dev_s *dev;
irqstate_t flags;
caninfo("TWAI%" PRIu8 "\n", port);
flags = enter_critical_section();
#ifdef CONFIG_ESPRESSIF_TWAI0
if (port == 0)
{
/* Enable power to the TWAI module and
* Enable clocking to the TWAI module
*/
periph_module_reset(PERIPH_TWAI0_MODULE);
periph_module_enable(PERIPH_TWAI0_MODULE);
/* Configure CAN GPIO pins */
esp_gpio_matrix_out(CONFIG_ESPRESSIF_TWAI0_TXPIN, TWAI0_TX_IDX, 0, 0);
esp_configgpio(CONFIG_ESPRESSIF_TWAI0_TXPIN, TX_PIN_ATTR);
esp_configgpio(CONFIG_ESPRESSIF_TWAI0_RXPIN, RX_PIN_ATTR);
esp_gpio_matrix_in(CONFIG_ESPRESSIF_TWAI0_RXPIN, TWAI0_RX_IDX, 0);
dev = &g_twai0dev;
}
else
#endif
#ifdef CONFIG_ESPRESSIF_TWAI1
if (port == 1)
{
/* Enable power to the TWAI module and
* Enable clocking to the TWAI module
*/
periph_module_reset(PERIPH_TWAI1_MODULE);
periph_module_enable(PERIPH_TWAI1_MODULE);
/* Configure CAN GPIO pins */
esp_gpio_matrix_out(CONFIG_ESPRESSIF_TWAI1_TXPIN, TWAI1_TX_IDX, 0, 0);
esp_configgpio(CONFIG_ESPRESSIF_TWAI1_TXPIN, TX_PIN_ATTR);
esp_configgpio(CONFIG_ESPRESSIF_TWAI1_RXPIN, RX_PIN_ATTR);
esp_gpio_matrix_in(CONFIG_ESPRESSIF_TWAI1_RXPIN, TWAI1_RX_IDX, 0);
dev = &g_twai1dev;
}
else
#endif
{
canerr("ERROR: Unsupported port: %d\n", port);
leave_critical_section(flags);
return NULL;
}
/* Then just perform a TWAI reset operation */
esp_twai_reset(dev);
leave_critical_section(flags);
return dev;
}
#endif /* CONFIG_ESPRESSIF_TWAI */

View File

@ -0,0 +1,76 @@
/****************************************************************************
* arch/risc-v/src/common/espressif/esp_twai.h
*
* 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.
*
****************************************************************************/
#ifndef __ARCH_RISCV_SRC_COMMON_ESPRESSIF_ESP_TWAI_H
#define __ARCH_RISCV_SRC_COMMON_ESPRESSIF_ESP_TWAI_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <nuttx/can/can.h>
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/****************************************************************************
* Public Types
****************************************************************************/
/****************************************************************************
* Public Data
****************************************************************************/
#ifndef __ASSEMBLY__
#ifdef __cplusplus
extern "C"
{
#endif
/****************************************************************************
* Public Functions Prototypes
****************************************************************************/
/****************************************************************************
* Name: esp_twaiinitialize
*
* Description:
* Initialize CAN port
*
* Input Parameters:
* port - Port number (for hardware that has multiple TWAI interfaces)
*
* Returned Value:
* Valid TWAI device structure reference on success; a NULL on failure
*
****************************************************************************/
#if defined(CONFIG_CAN) && defined(CONFIG_ESPRESSIF_TWAI)
struct can_dev_s *esp_twaiinitialize(int port);
#endif
#ifdef __cplusplus
}
#endif
#endif /* __ASSEMBLY__ */
#endif /* __ARCH_RISCV_SRC_COMMON_ESPRESSIF_ESP_TWAI_H */

View File

@ -51,6 +51,7 @@ INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)/chip/$(ESP_HAL_3RDPARTY_REPO)/compone
INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)/chip/$(ESP_HAL_3RDPARTY_REPO)/components/soc/$(CHIP_SERIES)/include
INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)/chip/$(ESP_HAL_3RDPARTY_REPO)/components/spi_flash/include
INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)/chip/$(ESP_HAL_3RDPARTY_REPO)/components/spi_flash/include/spi_flash
INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)/chip/$(ESP_HAL_3RDPARTY_REPO)/components/driver/twai/include
ifeq ($(CONFIG_ESPRESSIF_SIMPLE_BOOT),y)
INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)/chip/$(ESP_HAL_3RDPARTY_REPO)/components/bootloader_support/include
@ -146,6 +147,8 @@ ifeq ($(CONFIG_ESPRESSIF_SIMPLE_BOOT),y)
CHIP_CSRCS += chip/$(ESP_HAL_3RDPARTY_REPO)/components/esp_rom/patches/esp_rom_spiflash.c
CHIP_CSRCS += chip/$(ESP_HAL_3RDPARTY_REPO)/components/efuse/src/esp_efuse_fields.c
CHIP_CSRCS += chip/$(ESP_HAL_3RDPARTY_REPO)/components/efuse/src/efuse_controller/keys/with_key_purposes/esp_efuse_api_key.c
CHIP_CSRCS += chip/$(ESP_HAL_3RDPARTY_REPO)/components/hal/twai_hal.c
CHIP_CSRCS += chip/$(ESP_HAL_3RDPARTY_REPO)/components/hal/twai_hal_iram.c
LDFLAGS += --wrap=bootloader_print_banner
endif

View File

@ -51,6 +51,7 @@ INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)/chip/$(ESP_HAL_3RDPARTY_REPO)/compone
INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)/chip/$(ESP_HAL_3RDPARTY_REPO)/components/soc/$(CHIP_SERIES)/include
INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)/chip/$(ESP_HAL_3RDPARTY_REPO)/components/spi_flash/include
INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)/chip/$(ESP_HAL_3RDPARTY_REPO)/components/spi_flash/include/spi_flash
INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)/chip/$(ESP_HAL_3RDPARTY_REPO)/components/driver/twai/include
ifeq ($(CONFIG_ESPRESSIF_SIMPLE_BOOT),y)
INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)/chip/$(ESP_HAL_3RDPARTY_REPO)/components/bootloader_support/include
@ -127,6 +128,8 @@ CHIP_CSRCS += chip/$(ESP_HAL_3RDPARTY_REPO)/components/riscv/interrupt.c
CHIP_CSRCS += chip/$(ESP_HAL_3RDPARTY_REPO)/components/soc/$(CHIP_SERIES)/gpio_periph.c
CHIP_CSRCS += chip/$(ESP_HAL_3RDPARTY_REPO)/components/soc/$(CHIP_SERIES)/ledc_periph.c
CHIP_CSRCS += chip/$(ESP_HAL_3RDPARTY_REPO)/components/soc/$(CHIP_SERIES)/rmt_periph.c
CHIP_CSRCS += chip/$(ESP_HAL_3RDPARTY_REPO)/components/hal/twai_hal_iram.c
CHIP_CSRCS += chip/$(ESP_HAL_3RDPARTY_REPO)/components/hal/twai_hal.c
ifeq ($(CONFIG_ESPRESSIF_SIMPLE_BOOT),y)
CHIP_CSRCS += chip/$(ESP_HAL_3RDPARTY_REPO)/nuttx/src/bootloader_banner_wrap.c

View File

@ -51,6 +51,7 @@ INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)/chip/$(ESP_HAL_3RDPARTY_REPO)/compone
INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)/chip/$(ESP_HAL_3RDPARTY_REPO)/components/soc/$(CHIP_SERIES)/include
INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)/chip/$(ESP_HAL_3RDPARTY_REPO)/components/spi_flash/include
INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)/chip/$(ESP_HAL_3RDPARTY_REPO)/components/spi_flash/include/spi_flash
INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)/chip/$(ESP_HAL_3RDPARTY_REPO)/components/driver/twai/include
ifeq ($(CONFIG_ESPRESSIF_SIMPLE_BOOT),y)
INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)/chip/$(ESP_HAL_3RDPARTY_REPO)/components/bootloader_support/include
@ -152,6 +153,8 @@ ifeq ($(CONFIG_ESPRESSIF_SIMPLE_BOOT),y)
CHIP_CSRCS += chip/$(ESP_HAL_3RDPARTY_REPO)/components/esp_rom/patches/esp_rom_spiflash.c
CHIP_CSRCS += chip/$(ESP_HAL_3RDPARTY_REPO)/components/efuse/src/esp_efuse_fields.c
CHIP_CSRCS += chip/$(ESP_HAL_3RDPARTY_REPO)/components/efuse/src/efuse_controller/keys/with_key_purposes/esp_efuse_api_key.c
CHIP_CSRCS += chip/$(ESP_HAL_3RDPARTY_REPO)/components/hal/twai_hal.c
CHIP_CSRCS += chip/$(ESP_HAL_3RDPARTY_REPO)/components/hal/twai_hal_iram.c
LDFLAGS += --wrap=bootloader_print_banner
endif

View File

@ -32,6 +32,10 @@ ifeq ($(CONFIG_ESPRESSIF_SPIFLASH),y)
CSRCS += esp_board_spiflash.c
endif
ifeq ($(CONFIG_ESPRESSIF_TWAI),y)
CSRCS += esp_board_twai.c
endif
DEPPATH += --dep-path src
VPATH += :src
CFLAGS += ${INCDIR_PREFIX}$(TOPDIR)$(DELIM)arch$(DELIM)$(CONFIG_ARCH)$(DELIM)src$(DELIM)board$(DELIM)src

View File

@ -0,0 +1,94 @@
/****************************************************************************
* boards/risc-v/esp32c3/common/src/esp_board_twai.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 <errno.h>
#include <debug.h>
#include <nuttx/can/can.h>
#include <arch/board/board.h>
#include "espressif/esp_twai.h"
#ifdef CONFIG_CAN
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#define TWAI_PORT 0
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: board_twai_setup
*
* Description:
* Initialize TWAI and register the TWAI device
*
* Input Parameters:
* None
*
* Returned Value:
* Zero (OK) is returned on success; A negated errno value is returned on
* any failure.
*
****************************************************************************/
int board_twai_setup(void)
{
#ifdef CONFIG_ESPRESSIF_TWAI
struct can_dev_s *twai;
int ret;
/* Call esp_twaiinitialize() to get an instance of the TWAI
* interface
* */
twai = esp_twaiinitialize(TWAI_PORT);
if (twai == NULL)
{
canerr("ERROR: Failed to get TWAI interface\n");
return -ENODEV;
}
/* Register the TWAI driver at "/dev/can0" */
ret = can_register("/dev/can0", twai);
if (ret < 0)
{
canerr("ERROR: TWAI0 register failed: %d\n", ret);
return ret;
}
return OK;
#else
return -ENODEV;
#endif
}
#endif /* CONFIG_CAN */

View File

@ -0,0 +1,48 @@
#
# This file is autogenerated: PLEASE DO NOT EDIT IT.
#
# You can use "make menuconfig" to make any modifications to the installed .config file.
# You can then do "make savedefconfig" to generate a new defconfig file that includes your
# modifications.
#
# CONFIG_NSH_ARGCAT is not set
# CONFIG_NSH_CMDOPT_HEXDUMP is not set
CONFIG_ARCH="risc-v"
CONFIG_ARCH_BOARD="esp32c3-generic"
CONFIG_ARCH_BOARD_COMMON=y
CONFIG_ARCH_BOARD_ESP32C3_GENERIC=y
CONFIG_ARCH_CHIP="esp32c3"
CONFIG_ARCH_CHIP_ESP32C3_GENERIC=y
CONFIG_ARCH_INTERRUPTSTACK=1536
CONFIG_ARCH_RISCV=y
CONFIG_ARCH_STACKDUMP=y
CONFIG_BOARDCTL_RESET=y
CONFIG_BOARD_LOOPSPERMSEC=15000
CONFIG_BUILTIN=y
CONFIG_DEV_ZERO=y
CONFIG_ESPRESSIF_TWAI0=y
CONFIG_EXAMPLES_CAN=y
CONFIG_FS_PROCFS=y
CONFIG_IDLETHREAD_STACKSIZE=2048
CONFIG_INIT_ENTRYPOINT="nsh_main"
CONFIG_INTELHEX_BINARY=y
CONFIG_LIBC_PERROR_STDOUT=y
CONFIG_LIBC_STRERROR=y
CONFIG_NFILE_DESCRIPTORS_PER_BLOCK=6
CONFIG_NSH_ARCHINIT=y
CONFIG_NSH_BUILTIN_APPS=y
CONFIG_NSH_FILEIOSIZE=512
CONFIG_NSH_READLINE=y
CONFIG_NSH_STRERROR=y
CONFIG_PREALLOC_TIMERS=0
CONFIG_RR_INTERVAL=200
CONFIG_SCHED_BACKTRACE=y
CONFIG_SCHED_WAITPID=y
CONFIG_START_DAY=29
CONFIG_START_MONTH=11
CONFIG_START_YEAR=2019
CONFIG_SYSTEM_DUMPSTACK=y
CONFIG_SYSTEM_NSH=y
CONFIG_TESTING_GETPRIME=y
CONFIG_TESTING_OSTEST=y
CONFIG_UART0_SERIAL_CONSOLE=y

View File

@ -81,6 +81,25 @@
int esp_bringup(void);
/****************************************************************************
* Name: board_twai_setup
*
* Description:
* Initialize TWAI and register the TWAI device
*
* Input Parameters:
* None
*
* Returned Value:
* Zero (OK) is returned on success; A negated errno value is returned on
* any failure.
*
****************************************************************************/
#ifdef CONFIG_ESPRESSIF_TWAI
int board_twai_setup(void);
#endif
/****************************************************************************
* Name: esp_gpio_init
*

View File

@ -184,6 +184,17 @@ int esp_bringup(void)
}
#endif
#ifdef CONFIG_ESPRESSIF_TWAI
/* Initialize TWAI and register the TWAI driver. */
ret = board_twai_setup();
if (ret < 0)
{
syslog(LOG_ERR, "ERROR: board_twai_setup failed: %d\n", ret);
}
#endif
#ifdef CONFIG_DEV_GPIO
ret = esp_gpio_init();
if (ret < 0)

View File

@ -32,6 +32,10 @@ ifeq ($(CONFIG_ESPRESSIF_SPIFLASH),y)
CSRCS += esp_board_spiflash.c
endif
ifeq ($(CONFIG_ESPRESSIF_TWAI),y)
CSRCS += esp_board_twai.c
endif
DEPPATH += --dep-path src
VPATH += :src
CFLAGS += ${INCDIR_PREFIX}$(TOPDIR)$(DELIM)arch$(DELIM)$(CONFIG_ARCH)$(DELIM)src$(DELIM)board$(DELIM)src

View File

@ -0,0 +1,105 @@
/****************************************************************************
* boards/risc-v/esp32c6/common/src/esp_board_twai.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 <errno.h>
#include <debug.h>
#include <nuttx/can/can.h>
#include <arch/board/board.h>
#include "espressif/esp_twai.h"
#ifdef CONFIG_CAN
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: board_twai_setup
*
* Description:
* Initialize TWAI and register the TWAI device
*
* Input Parameters:
* port - Port number (for hardware that has multiple TWAI interfaces)
*
* Returned Value:
* Zero (OK) is returned on success; A negated errno value is returned on
* any failure.
*
****************************************************************************/
int board_twai_setup(int port)
{
#ifdef CONFIG_ESPRESSIF_TWAI
struct can_dev_s *twai;
int ret;
/* Call esp_twaiinitialize() to get an instance of the TWAI
* interface
* */
twai = esp_twaiinitialize(port);
if (twai == NULL)
{
canerr("ERROR: Failed to get TWAI interface\n");
return -ENODEV;
}
#ifdef CONFIG_ESPRESSIF_TWAI0
/* Register the TWAI driver at "/dev/can0" */
ret = can_register("/dev/can0", twai);
if (ret < 0)
{
canerr("ERROR: TWAI0 register failed: %d\n", ret);
return ret;
}
#endif /* CONFIG_ESPRESSIF_TWAI0 */
#ifdef CONFIG_ESPRESSIF_TWAI1
/* Register the TWAI driver at "/dev/can1" */
ret = can_register("/dev/can1", twai);
if (ret < 0)
{
canerr("ERROR: TWAI1 register failed: %d\n", ret);
return ret;
}
#endif /* CONFIG_ESPRESSIF_TWAI1 */
return OK;
#else
return -ENODEV;
#endif
}
#endif /* CONFIG_CAN */

View File

@ -0,0 +1,50 @@
#
# This file is autogenerated: PLEASE DO NOT EDIT IT.
#
# You can use "make menuconfig" to make any modifications to the installed .config file.
# You can then do "make savedefconfig" to generate a new defconfig file that includes your
# modifications.
#
# CONFIG_NSH_ARGCAT is not set
# CONFIG_NSH_CMDOPT_HEXDUMP is not set
CONFIG_ARCH="risc-v"
CONFIG_ARCH_BOARD="esp32c6-devkitc"
CONFIG_ARCH_BOARD_COMMON=y
CONFIG_ARCH_BOARD_ESP32C6_DEVKITC=y
CONFIG_ARCH_CHIP="esp32c6"
CONFIG_ARCH_CHIP_ESP32C6=y
CONFIG_ARCH_CHIP_ESP32C6WROOM1=y
CONFIG_ARCH_INTERRUPTSTACK=2048
CONFIG_ARCH_RISCV=y
CONFIG_ARCH_STACKDUMP=y
CONFIG_BOARDCTL_RESET=y
CONFIG_BOARD_LOOPSPERMSEC=15000
CONFIG_BUILTIN=y
CONFIG_DEV_ZERO=y
CONFIG_ESPRESSIF_ESP32C6=y
CONFIG_ESPRESSIF_TWAI0=y
CONFIG_EXAMPLES_CAN=y
CONFIG_FS_PROCFS=y
CONFIG_IDLETHREAD_STACKSIZE=2048
CONFIG_INIT_ENTRYPOINT="nsh_main"
CONFIG_INTELHEX_BINARY=y
CONFIG_LIBC_PERROR_STDOUT=y
CONFIG_LIBC_STRERROR=y
CONFIG_NFILE_DESCRIPTORS_PER_BLOCK=6
CONFIG_NSH_ARCHINIT=y
CONFIG_NSH_BUILTIN_APPS=y
CONFIG_NSH_FILEIOSIZE=512
CONFIG_NSH_READLINE=y
CONFIG_NSH_STRERROR=y
CONFIG_PREALLOC_TIMERS=0
CONFIG_RR_INTERVAL=200
CONFIG_SCHED_BACKTRACE=y
CONFIG_SCHED_WAITPID=y
CONFIG_START_DAY=29
CONFIG_START_MONTH=11
CONFIG_START_YEAR=2019
CONFIG_SYSTEM_DUMPSTACK=y
CONFIG_SYSTEM_NSH=y
CONFIG_TESTING_GETPRIME=y
CONFIG_TESTING_OSTEST=y
CONFIG_UART0_SERIAL_CONSOLE=y

View File

@ -81,6 +81,25 @@
int esp_bringup(void);
/****************************************************************************
* Name: board_twai_setup
*
* Description:
* Initialize TWAI and register the TWAI device
*
* Input Parameters:
* port - Port number (for hardware that has multiple TWAI interfaces)
*
* Returned Value:
* Zero (OK) is returned on success; A negated errno value is returned on
* any failure.
*
****************************************************************************/
#ifdef CONFIG_ESPRESSIF_TWAI
int board_twai_setup(int port);
#endif
/****************************************************************************
* Name: esp_gpio_init
*

View File

@ -184,6 +184,28 @@ int esp_bringup(void)
}
#endif
#ifdef CONFIG_ESPRESSIF_TWAI0
/* Initialize TWAI and register the TWAI driver. */
ret = board_twai_setup(0);
if (ret < 0)
{
syslog(LOG_ERR, "ERROR: TWAI0 board_twai_setup failed: %d\n", ret);
}
#endif
#ifdef CONFIG_ESPRESSIF_TWAI1
/* Initialize TWAI and register the TWAI driver. */
ret = board_twai_setup(1);
if (ret < 0)
{
syslog(LOG_ERR, "ERROR: TWAI1 board_twai_setup failed: %d\n", ret);
}
#endif
#ifdef CONFIG_DEV_GPIO
ret = esp_gpio_init();
if (ret < 0)

View File

@ -0,0 +1,50 @@
#
# This file is autogenerated: PLEASE DO NOT EDIT IT.
#
# You can use "make menuconfig" to make any modifications to the installed .config file.
# You can then do "make savedefconfig" to generate a new defconfig file that includes your
# modifications.
#
# CONFIG_NSH_ARGCAT is not set
# CONFIG_NSH_CMDOPT_HEXDUMP is not set
CONFIG_ARCH="risc-v"
CONFIG_ARCH_BOARD="esp32c6-devkitm"
CONFIG_ARCH_BOARD_COMMON=y
CONFIG_ARCH_BOARD_ESP32C6_DEVKITM=y
CONFIG_ARCH_CHIP="esp32c6"
CONFIG_ARCH_CHIP_ESP32C6=y
CONFIG_ARCH_CHIP_ESP32C6MINI1=y
CONFIG_ARCH_INTERRUPTSTACK=2048
CONFIG_ARCH_RISCV=y
CONFIG_ARCH_STACKDUMP=y
CONFIG_BOARDCTL_RESET=y
CONFIG_BOARD_LOOPSPERMSEC=15000
CONFIG_BUILTIN=y
CONFIG_DEV_ZERO=y
CONFIG_ESPRESSIF_ESP32C6=y
CONFIG_ESPRESSIF_TWAI0=y
CONFIG_EXAMPLES_CAN=y
CONFIG_FS_PROCFS=y
CONFIG_IDLETHREAD_STACKSIZE=2048
CONFIG_INIT_ENTRYPOINT="nsh_main"
CONFIG_INTELHEX_BINARY=y
CONFIG_LIBC_PERROR_STDOUT=y
CONFIG_LIBC_STRERROR=y
CONFIG_NFILE_DESCRIPTORS_PER_BLOCK=6
CONFIG_NSH_ARCHINIT=y
CONFIG_NSH_BUILTIN_APPS=y
CONFIG_NSH_FILEIOSIZE=512
CONFIG_NSH_READLINE=y
CONFIG_NSH_STRERROR=y
CONFIG_PREALLOC_TIMERS=0
CONFIG_RR_INTERVAL=200
CONFIG_SCHED_BACKTRACE=y
CONFIG_SCHED_WAITPID=y
CONFIG_START_DAY=29
CONFIG_START_MONTH=11
CONFIG_START_YEAR=2019
CONFIG_SYSTEM_DUMPSTACK=y
CONFIG_SYSTEM_NSH=y
CONFIG_TESTING_GETPRIME=y
CONFIG_TESTING_OSTEST=y
CONFIG_UART0_SERIAL_CONSOLE=y

View File

@ -81,6 +81,25 @@
int esp_bringup(void);
/****************************************************************************
* Name: board_twai_setup
*
* Description:
* Initialize TWAI and register the TWAI device
*
* Input Parameters:
* port - Port number (for hardware that has multiple TWAI interfaces)
*
* Returned Value:
* Zero (OK) is returned on success; A negated errno value is returned on
* any failure.
*
****************************************************************************/
#ifdef CONFIG_ESPRESSIF_TWAI
int board_twai_setup(int port);
#endif
/****************************************************************************
* Name: esp_gpio_init
*

View File

@ -184,6 +184,28 @@ int esp_bringup(void)
}
#endif
#ifdef CONFIG_ESPRESSIF_TWAI0
/* Initialize TWAI and register the TWAI driver. */
ret = board_twai_setup(0);
if (ret < 0)
{
syslog(LOG_ERR, "ERROR: board_twai_setup failed: %d\n", ret);
}
#endif
#ifdef CONFIG_ESPRESSIF_TWAI1
/* Initialize TWAI and register the TWAI driver. */
ret = board_twai_setup(1);
if (ret < 0)
{
syslog(LOG_ERR, "ERROR: board_twai_setup failed: %d\n", ret);
}
#endif
#ifdef CONFIG_DEV_GPIO
ret = esp_gpio_init();
if (ret < 0)

View File

@ -32,6 +32,10 @@ ifeq ($(CONFIG_ESPRESSIF_SPIFLASH),y)
CSRCS += esp_board_spiflash.c
endif
ifeq ($(CONFIG_ESPRESSIF_TWAI),y)
CSRCS += esp_board_twai.c
endif
DEPPATH += --dep-path src
VPATH += :src
CFLAGS += ${INCDIR_PREFIX}$(TOPDIR)$(DELIM)arch$(DELIM)$(CONFIG_ARCH)$(DELIM)src$(DELIM)board$(DELIM)src

View File

@ -0,0 +1,94 @@
/****************************************************************************
* boards/risc-v/esp32h2/common/src/esp_board_twai.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 <errno.h>
#include <debug.h>
#include <nuttx/can/can.h>
#include <arch/board/board.h>
#include "espressif/esp_twai.h"
#ifdef CONFIG_CAN
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#define TWAI_PORT 0
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: board_twai_setup
*
* Description:
* Initialize TWAI and register the TWAI device
*
* Input Parameters:
* None
*
* Returned Value:
* Zero (OK) is returned on success; A negated errno value is returned on
* any failure.
*
****************************************************************************/
int board_twai_setup(void)
{
#ifdef CONFIG_ESPRESSIF_TWAI
struct can_dev_s *twai;
int ret;
/* Call esp_twaiinitialize() to get an instance of the TWAI
* interface
* */
twai = esp_twaiinitialize(TWAI_PORT);
if (twai == NULL)
{
canerr("ERROR: Failed to get TWAI interface\n");
return -ENODEV;
}
/* Register the TWAI driver at "/dev/can0" */
ret = can_register("/dev/can0", twai);
if (ret < 0)
{
canerr("ERROR: TWAI0 register failed: %d\n", ret);
return ret;
}
return OK;
#else
return -ENODEV;
#endif
}
#endif /* CONFIG_CAN */

View File

@ -0,0 +1,49 @@
#
# This file is autogenerated: PLEASE DO NOT EDIT IT.
#
# You can use "make menuconfig" to make any modifications to the installed .config file.
# You can then do "make savedefconfig" to generate a new defconfig file that includes your
# modifications.
#
# CONFIG_NSH_ARGCAT is not set
# CONFIG_NSH_CMDOPT_HEXDUMP is not set
CONFIG_ARCH="risc-v"
CONFIG_ARCH_BOARD="esp32h2-devkit"
CONFIG_ARCH_BOARD_COMMON=y
CONFIG_ARCH_BOARD_ESP32H2_DEVKIT=y
CONFIG_ARCH_CHIP="esp32h2"
CONFIG_ARCH_CHIP_ESP32H2=y
CONFIG_ARCH_INTERRUPTSTACK=2048
CONFIG_ARCH_RISCV=y
CONFIG_ARCH_STACKDUMP=y
CONFIG_BOARDCTL_RESET=y
CONFIG_BOARD_LOOPSPERMSEC=15000
CONFIG_BUILTIN=y
CONFIG_DEV_ZERO=y
CONFIG_ESPRESSIF_ESP32H2=y
CONFIG_ESPRESSIF_TWAI0=y
CONFIG_EXAMPLES_CAN=y
CONFIG_FS_PROCFS=y
CONFIG_IDLETHREAD_STACKSIZE=2048
CONFIG_INIT_ENTRYPOINT="nsh_main"
CONFIG_INTELHEX_BINARY=y
CONFIG_LIBC_PERROR_STDOUT=y
CONFIG_LIBC_STRERROR=y
CONFIG_NFILE_DESCRIPTORS_PER_BLOCK=6
CONFIG_NSH_ARCHINIT=y
CONFIG_NSH_BUILTIN_APPS=y
CONFIG_NSH_FILEIOSIZE=512
CONFIG_NSH_READLINE=y
CONFIG_NSH_STRERROR=y
CONFIG_PREALLOC_TIMERS=0
CONFIG_RR_INTERVAL=200
CONFIG_SCHED_BACKTRACE=y
CONFIG_SCHED_WAITPID=y
CONFIG_START_DAY=29
CONFIG_START_MONTH=11
CONFIG_START_YEAR=2019
CONFIG_SYSTEM_DUMPSTACK=y
CONFIG_SYSTEM_NSH=y
CONFIG_TESTING_GETPRIME=y
CONFIG_TESTING_OSTEST=y
CONFIG_UART0_SERIAL_CONSOLE=y

View File

@ -81,6 +81,25 @@
int esp_bringup(void);
/****************************************************************************
* Name: board_twai_setup
*
* Description:
* Initialize TWAI and register the TWAI device
*
* Input Parameters:
* None
*
* Returned Value:
* Zero (OK) is returned on success; A negated errno value is returned on
* any failure.
*
****************************************************************************/
#ifdef CONFIG_ESPRESSIF_TWAI
int board_twai_setup(void);
#endif
/****************************************************************************
* Name: esp_gpio_init
*

View File

@ -184,6 +184,17 @@ int esp_bringup(void)
}
#endif
#ifdef CONFIG_ESPRESSIF_TWAI
/* Initialize TWAI and register the TWAI driver. */
ret = board_twai_setup();
if (ret < 0)
{
syslog(LOG_ERR, "ERROR: board_twai_setup failed: %d\n", ret);
}
#endif
#ifdef CONFIG_DEV_GPIO
ret = esp_gpio_init();
if (ret < 0)