boards/arm/tiva/tm4c123g-launchpad/: SPI CAN functionality on TM4C123GXL - ek-tm4c123gxl_spi_can.

This commit is contained in:
DisruptiveNL 2019-10-05 14:18:08 -06:00 committed by Gregory Nutt
parent a6b31e3f03
commit 8d435b2e2d
9 changed files with 429 additions and 16 deletions

View File

@ -16,6 +16,7 @@ Contents
I2C Tool
Using OpenOCD and GDB with an FT2232 JTAG emulator
TM4C123G LaunchPad Configuration Options
MCP2515 - SPI - CAN
Configurations
On-Board GPIO Usage
@ -447,8 +448,35 @@ USB Device Controller Functions
to communicate with UART0 on the TM4C123G over USB. Once the FT2232 VCP
driver is installed, Windows assigns a COM port number to the VCP channel.
MCP2515 - SPI - CAN
===================
I like CANbus, and having an MCP2515 CAN Bus Module laying around
gave me the idea to implement it on the TM4C123GXL (Launchpad).
Nuttx already had implemented it on the STM32. So a lot of work already
has been done. It uses SPI and with this Launchpad we use SSI.
Here is how I have the MCP2515 Module connected. But you can change
this with the settings in include/board.h and src/tm4c123g-launchpad.h.
Connector pinout that I am using:
--------------------------+----------------------------------------------
Connector CAN Module | Launchpad TM4C123GXL (SSI2_1)
--------------------------+----------------------------------------------
1 INT | PB0
2 SCK | PB4 (Clock)
3 SI | PB7 (MOSI = TX)
4 SO | PB6 (MISO = RX)
5 CS | PB5 (Chip Select)
6 GND | GND
7 VCC | VBUS (+5V)
--------------------------+----------------------------------------------
PS: I have to test the CS signal when adding it on a bus with multiple nodes.
TM4C123G LaunchPad Configuration Options
=======================================================
========================================
CONFIG_ARCH - Identifies the arch/ subdirectory. This should
be set to:
@ -561,6 +589,12 @@ boards/arm/tiva/tm4c123g-launchpad/configs/ and can be selected as follows:
Where <subdir> is one of the following:
mcp2515
=======
Configuration uses the MCP2515 SPI CAN part. See the section entitled
"MCP2515 - SPI - CAN" above.
nsh:
---
Configures the NuttShell (nsh) located at apps/examples/nsh. The

View File

@ -0,0 +1,66 @@
#
# 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_ARCH_FPU is not set
# CONFIG_NSH_DISABLE_IFCONFIG is not set
# CONFIG_NSH_DISABLE_PS is not set
CONFIG_ARCH="arm"
CONFIG_ARCH_BOARD="tm4c123g-launchpad"
CONFIG_ARCH_BOARD_TM4C123G_LAUNCHPAD=y
CONFIG_ARCH_CHIP="tiva"
CONFIG_ARCH_CHIP_TIVA=y
CONFIG_ARCH_CHIP_TM4C123=y
CONFIG_ARCH_CHIP_TM4C123GH6PM=y
CONFIG_ARCH_CHIP_TM4C=y
CONFIG_ARCH_STACKDUMP=y
CONFIG_BOARD_LOOPSPERMSEC=4531
CONFIG_BUILTIN=y
CONFIG_CAN=y
CONFIG_CAN_EXTID=y
CONFIG_CAN_MCP2515=y
CONFIG_DEBUG_FULLOPT=y
CONFIG_DEBUG_SYMBOLS=y
CONFIG_EXAMPLES_CAN=y
CONFIG_EXAMPLES_CAN_READ=y
CONFIG_MAX_TASKS=16
CONFIG_MAX_WDOGPARMS=2
CONFIG_MCP2515_PHASESEG1=3
CONFIG_MCP2515_PROPSEG=1
CONFIG_MCP2515_SPI_SCK_FREQUENCY=4000000
CONFIG_NFILE_DESCRIPTORS=8
CONFIG_NFILE_STREAMS=8
CONFIG_NSH_ARCHINIT=y
CONFIG_NSH_BUILTIN_APPS=y
CONFIG_NSH_FILEIOSIZE=512
CONFIG_NSH_LINELEN=64
CONFIG_NSH_READLINE=y
CONFIG_PREALLOC_MQ_MSGS=4
CONFIG_PREALLOC_TIMERS=4
CONFIG_PREALLOC_WDOGS=4
CONFIG_RAM_SIZE=32768
CONFIG_RAM_START=0x20000000
CONFIG_RAW_BINARY=y
CONFIG_RR_INTERVAL=200
CONFIG_SCHED_WAITPID=y
CONFIG_SPI=y
CONFIG_START_DAY=24
CONFIG_START_MONTH=3
CONFIG_START_YEAR=2013
CONFIG_SYSTEM_NSH=y
CONFIG_SYSTEM_SPITOOL=y
CONFIG_TASK_NAME_SIZE=0
CONFIG_TIVA_GPIOA_IRQS=y
CONFIG_TIVA_GPIOB_IRQS=y
CONFIG_TIVA_GPIOC_IRQS=y
CONFIG_TIVA_GPIOD_IRQS=y
CONFIG_TIVA_GPIOE_IRQS=y
CONFIG_TIVA_GPIOF_IRQS=y
CONFIG_TIVA_SSI2=y
CONFIG_TIVA_UART0=y
CONFIG_UART0_SERIAL_CONSOLE=y
CONFIG_USER_ENTRYPOINT="nsh_main"
CONFIG_WDOG_INTRESERVE=0

View File

@ -195,4 +195,13 @@
#define GPIO_UART1_RX GPIO_UART1_RX_1
#define GPIO_UART1_TX GPIO_UART1_TX_1
/* Pin SPI definitions ******************************************************/
/* Needed by: chip/common/tiva_ssi.c ****************************************/
#define GPIO_SSI2_RX GPIO_SSI2_RX_1
#define GPIO_SSI2_TX GPIO_SSI2_TX_1
#define GPIO_SSI2_CLK GPIO_SSI2_CLK_1
#define GPIO_SSI2_FSS GPIO_SSI2_FSS_1
#endif /* __BOARDS_ARM_TMC4C123G_LAUNCHPAD_INCLUDE_BOARD_H */

View File

@ -54,6 +54,10 @@ ifeq ($(CONFIG_TIVA_ADC),y)
CSRCS += tm4c_adc.c
endif
ifeq ($(CONFIG_CAN_MCP2515),y)
CSRCS += tm4c_mcp2515.c
endif
ifeq ($(CONFIG_MTD_AT24XX),y)
ifeq ($(CONFIG_TIVA_I2C0),y)
CSRCS += tm4c_at24.c

View File

@ -70,7 +70,7 @@
* devices on-board the Launchpad, but an external serial EEPROM module
* module was used.
*
* The Serial EEPROM was mounted on an external adaptor board and connected
* The Serial EEPROM was mounted on an external adapter board and connected
* to the LaunchPad thusly:
*
* - VCC -- VCC
@ -86,7 +86,7 @@
# undef HAVE_AT24
#endif
/* Can't support AT25 features if mountpoints are disabled or if we were not
/* Can't support AT25 features if mount points are disabled or if we were not
* asked to mount the AT25 part
*/
@ -178,6 +178,25 @@
GPIO_STRENGTH_2MA | GPIO_PADTYPE_STDWPU | \
GPIO_PORTF | GPIO_PIN_0)
#define SDCCS_GPIO (GPIO_FUNC_OUTPUT | GPIO_PADTYPE_STDWPU | GPIO_STRENGTH_4MA | \
GPIO_VALUE_ONE | GPIO_PORTG | 1)
/* MCP2551: Did not test the CS settings. GPIO_STRENGTH could be different. */
#ifdef CONFIG_CAN_MCP2515
# define GPIO_MCP2515_IRQ (GPIO_FUNC_INTERRUPT | GPIO_INT_FALLINGEDGE | \
GPIO_PORTB | GPIO_PIN_0)
# define GPIO_SSI2_CLK_1 (GPIO_FUNC_PFIO | GPIO_ALT_2 | GPIO_PORTB | \
GPIO_PIN_4)
# define GPIO_SSI2_RX_1 (GPIO_FUNC_PFIO | GPIO_ALT_2 | GPIO_PORTB | \
GPIO_PIN_6)
# define GPIO_SSI2_TX_1 (GPIO_FUNC_PFIO | GPIO_ALT_2 | GPIO_PORTB | \
GPIO_PIN_7)
# define GPIO_MCP2515_CS (GPIO_FUNC_OUTPUT | GPIO_PADTYPE_STDWPU | \
GPIO_STRENGTH_4MA | GPIO_VALUE_ONE | GPIO_PORTB | \
GPIO_PIN_5)
#endif
/****************************************************************************
* Public Functions
****************************************************************************/
@ -252,5 +271,17 @@ int tm4c_at24_automount(int minor);
int tiva_timer_configure(void);
#endif
/****************************************************************************
* Name: tiva_mcp2515initialize
*
* Description:
* Initialize and register the MCP2515 CAN driver.
*
****************************************************************************/
#ifdef CONFIG_CAN_MCP2515
int tiva_mcp2515initialize(FAR const char *devpath);
#endif
#endif /* __ASSEMBLY__ */
#endif /* __BOARDS_ARM_TIVA_TM4C123G_LAUNCHPAD_TM4C123G_LAUNCHPAD_H */

View File

@ -48,14 +48,6 @@
#include "up_internal.h"
#include "tm4c123g-launchpad.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Public Functions
****************************************************************************/
@ -73,24 +65,25 @@
void tiva_boardinitialize(void)
{
#if defined(CONFIG_TIVA_SSI0) || defined(CONFIG_TIVA_SSI1) || \
defined(CONFIG_TIVA_SSI2)
/* Configure SPI chip selects if
* 1) SSI is not disabled, and
* 2) the weak function
* tm4c_ssidev_initialize() has been brought into the link.
* 2) the weak function tm4c_ssidev_initialize() has been brought into the
* link.
*/
/* The TM4C123G LaunchPad microSD CS and OLED are on SSI0 */
#if defined(CONFIG_TIVA_SSI0) || defined(CONFIG_TIVA_SSI1)
if (tm4c_ssidev_initialize)
{
tm4c_ssidev_initialize();
}
#endif
#ifdef CONFIG_ARCH_LEDS
/* Configure on-board LEDs if LED support has been selected. */
#ifdef CONFIG_ARCH_LEDS
tm4c_led_initialize();
#endif
}

View File

@ -95,6 +95,18 @@ int tm4c_bringup(void)
}
#endif /* CONFIG_TIVA_TIMER */
#ifdef CONFIG_CAN_MCP2515
/* Configure and initialize the MCP2515 CAN device */
ret = tiva_mcp2515initialize("/dev/can0");
if (ret < 0)
{
syslog(LOG_ERR, "ERROR: stm32_mcp2515initialize() failed: %d\n", ret);
return ret;
}
#endif
UNUSED(ret);
return ret;
}

View File

@ -0,0 +1,253 @@
/****************************************************************************
* boards/arm/tiva/tm4c123g-launchpad/src/tiva_mcp2515.c
*
* Copyright (C) 2017 Alan Carvalho de Assis. All rights reserved.
* Author: Alan Carvalho de Assis <acassis@gmail.com>
* Modified: Ben <disruptivesolutionsnl@gmail.com>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <errno.h>
#include <debug.h>
#include <nuttx/spi/spi.h>
#include <nuttx/can/mcp2515.h>
#include "chip.h"
#include "tiva_ssi.h"
#include "tm4c123g-launchpad.h"
#if defined(CONFIG_SPI) && defined(CONFIG_TIVA_SSI2) && \
defined(CONFIG_CAN_MCP2515)
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#define MCP2515_SPI_PORTNO 2 /* On SPI2 */
/****************************************************************************
* Private Types
****************************************************************************/
struct tiva_mcp2515config_s
{
/* Configuration structure as seen by the MCP2515 driver */
struct mcp2515_config_s config;
/* Additional private definitions only known to this driver */
FAR struct mcp2515_can_s *handle; /* The MCP2515 driver handle */
mcp2515_handler_t handler; /* The MCP2515 interrupt handler */
FAR void *arg; /* Argument to pass to the interrupt handler */
};
/****************************************************************************
* Static Function Prototypes
****************************************************************************/
/* IRQ/GPIO access callbacks. These operations all hidden behind callbacks
* to isolate the MCP2515 driver from differences in GPIO interrupt handling
* by varying boards and MCUs.
*
* attach - Attach the MCP2515 interrupt handler to the GPIO interrupt
*/
static int mcp2515_attach(FAR struct mcp2515_config_s *state,
mcp2515_handler_t handler, FAR void *arg);
/****************************************************************************
* Private Data
****************************************************************************/
/* A reference to a structure of this type must be passed to the MCP2515
* driver. This structure provides information about the configuration
* of the MCP2515 and provides some board-specific hooks.
*
* Memory for this structure is provided by the caller. It is not copied
* by the driver and is presumed to persist while the driver is active. The
* memory must be writable because, under certain circumstances, the driver
* may modify frequency or X plate resistance values.
*/
static struct tiva_mcp2515config_s g_mcp2515config =
{
.config =
{
.spi = NULL,
.baud = 0, /* REVISIT. Probably broken by commit eb7373cedfa */
.btp = 0, /* REVISIT. Probably broken by commit eb7373cedfa */
.devid = 0,
.mode = 0, /* REVISIT. Probably broken by commit eb7373cedfa */
.nfilters = 6,
#ifdef MCP2515_LOOPBACK
.loopback = false;
#endif
.attach = mcp2515_attach,
},
};
/****************************************************************************
* Private Functions
****************************************************************************/
/* This is the MCP2515 Interrupt handler */
int mcp2515_interrupt(int irq, FAR void *context, FAR void *arg)
{
FAR struct tiva_mcp2515config_s *priv =
(FAR struct tiva_mcp2515config_s *)arg;
DEBUGASSERT(priv != NULL);
/* Verify that we have a handler attached */
if (priv->handler)
{
/* Yes.. forward with interrupt along with its argument */
priv->handler(&priv->config, priv->arg);
}
return OK;
}
static int mcp2515_attach(FAR struct mcp2515_config_s *state,
mcp2515_handler_t handler, FAR void *arg)
{
FAR struct tiva_mcp2515config_s *priv =
(FAR struct tiva_mcp2515config_s *)state;
irqstate_t flags;
caninfo("Saving handler %p\n", handler);
flags = enter_critical_section();
priv->handler = handler;
priv->arg = arg;
/* Configure the interrupt for falling edge */
(void)tiva_configgpio(GPIO_MCP2515_IRQ);
leave_critical_section(flags);
return OK;
}
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: tiva_mcp2515initialize
*
* Description:
* Initialize and register the MCP2515 RFID driver.
*
* Input Parameters:
* devpath - The full path to the driver to register. E.g., "/dev/rfid0"
*
* Returned Value:
* Zero (OK) on success; a negated errno value on failure.
*
****************************************************************************/
int tiva_mcp2515initialize(FAR const char *devpath)
{
FAR struct spi_dev_s *spi;
FAR struct can_dev_s *can;
FAR struct mcp2515_can_s *mcp2515;
int ret;
/* Check if we are already initialized */
if (!g_mcp2515config.handle)
{
sninfo("Initializing\n");
/* Configure the MCP2515 interrupt pin as an input */
(void)tiva_configgpio(GPIO_MCP2515_IRQ);
spi = tiva_ssibus_initialize(MCP2515_SPI_PORTNO);
if (!spi)
{
return -ENODEV;
}
/* Save the SPI instance in the mcp2515_config_s structure */
g_mcp2515config.config.spi = spi;
/* Instantiate the MCP2515 CAN Driver */
mcp2515 = mcp2515_instantiate(&g_mcp2515config.config);
if (mcp2515 == NULL)
{
canerr("ERROR: Failed to get MCP2515 Driver Loaded\n");
return -ENODEV;
}
/* Save the opaque structure */
g_mcp2515config.handle = mcp2515;
/* Initialize the CAN Device with the MCP2515 operations */
can = mcp2515_initialize(mcp2515);
if (can == NULL)
{
canerr("ERROR: Failed to get CAN interface\n");
return -ENODEV;
}
/* Register the CAN driver at "/dev/can0" */
ret = can_register(devpath, can);
if (ret < 0)
{
canerr("ERROR: can_register failed: %d\n", ret);
return ret;
}
}
return OK;
}
#endif /* CONFIG_SPI && CONFIG_CAN_MCP2515 */

View File

@ -53,7 +53,7 @@
/* The TM4C123G LaunchPad microSD CS is on SSI0 */
#if defined(CONFIG_TIVA_SSI0) || defined(CONFIG_TIVA_SSI1)
#if defined(CONFIG_TIVA_SSI0) || defined(CONFIG_TIVA_SSI1) || defined(CONFIG_TIVA_SSI2)
/****************************************************************************
* Pre-processor Definitions
@ -79,6 +79,9 @@
void weak_function tm4c_ssidev_initialize(void)
{
#ifdef CONFIG_CAN_MCP2515
(void)tiva_configgpio(GPIO_MCP2515_CS); /* mcp2515 chip select */
#endif
}
/****************************************************************************
@ -108,6 +111,13 @@ void tiva_ssiselect(FAR struct spi_dev_s *dev, uint32_t devid, bool selected)
selected ? "assert" : "de-assert");
ssi_dumpgpio("tiva_ssiselect() Entry");
ssi_dumpgpio("tiva_ssiselect() Exit");
#if defined(CONFIG_CAN_MCP2515)
if (devid == SPIDEV_CANBUS(0))
{
tiva_gpiowrite(GPIO_MCP2515_CS, !selected);
}
#endif
}
uint8_t tiva_ssistatus(FAR struct spi_dev_s *dev, uint32_t devid)
@ -117,3 +127,4 @@ uint8_t tiva_ssistatus(FAR struct spi_dev_s *dev, uint32_t devid)
}
#endif /* CONFIG_TIVA_SSI0 || CONFIG_TIVA_SSI1 */