feature: driver: Add a Linux SPI into simulator.

When SIM_SPI is valid, a specified Linux SPI device ‘spidevN.P’(N is bus number and P is CS number) is attached to nuttx simulator, shown as 'spi0' under /dev. One may type spi command (need SPITOOL valid) in NSH to control the Linux SPI and exchange data, other devices such sensors can use it to debug in simulator on a Ubuntu PC. Note that a USB<>SPI module (e.g. CH341A/B) should be plugged in to achieve Linux SPI ports.

Change-Id: I275b2c2bbf6d14bcdf514c89efb9a2264d69e9a3
Signed-off-by: liucheng5 <liucheng5@xiaomi.com>
This commit is contained in:
liucheng5
2021-09-02 17:09:10 +08:00
committed by Xiang Xiao
parent 7049687e71
commit fdb9576d7a
9 changed files with 1005 additions and 1 deletions
+25
View File
@@ -562,6 +562,31 @@ endchoice
endif endif
config SIM_SPI
bool "Simulated SPI port"
default n
select SPI
---help---
Build in support for simulated spi port
if SIM_SPI
choice
prompt "Simulated SPI Type"
default SIM_SPI_LINUX
config SIM_SPI_LINUX
bool "Linux SPI Character Dev"
depends on HOST_LINUX
---help---
Attach a Linux SPI port via the character device
interface. To achieve a SPI port on Linux host, it is
recommended to use a USB<>SPI device such as CH341A/B.
endchoice
endif
config SIM_UART_NUMBER config SIM_UART_NUMBER
int "The number of tty ports on sim platform, range is 0~4" int "The number of tty ports on sim platform, range is 0~4"
default 0 default 0
+10
View File
@@ -179,6 +179,16 @@ ifeq ($(CONFIG_SIM_I2CBUS_LINUX),y)
HOSTSRCS += up_i2cbuslinux.c HOSTSRCS += up_i2cbuslinux.c
endif endif
ifeq ($(CONFIG_SIM_SPI_LINUX),y)
HOSTSRCS += up_spilinux.c
up_spilinux.c: config.h
config.h: $(TOPDIR)/include/nuttx/config.h
@echo "CP: $<"
$(Q) cp $< $@
endif
ifeq ($(CONFIG_RPTUN),y) ifeq ($(CONFIG_RPTUN),y)
CSRCS += up_rptun.c CSRCS += up_rptun.c
endif endif
+7
View File
@@ -352,6 +352,13 @@ struct i2c_master_s *sim_i2cbus_initialize(int bus);
int sim_i2cbus_uninitialize(struct i2c_master_s *dev); int sim_i2cbus_uninitialize(struct i2c_master_s *dev);
#endif #endif
/* up_spi*.c ****************************************************************/
#ifdef CONFIG_SIM_SPI
struct spi_dev_s *sim_spi_initialize(const char *filename);
int sim_spi_uninitialize(struct spi_dev_s *dev);
#endif
/* Debug ********************************************************************/ /* Debug ********************************************************************/
#ifdef CONFIG_STACK_COLORATION #ifdef CONFIG_STACK_COLORATION
+156
View File
@@ -0,0 +1,156 @@
/****************************************************************************
* arch/sim/src/sim/up_spi.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_SIM_SRC_SIM_SPI_H_
#define _ARCH_SIM_SRC_SIM_SPI_H_
/****************************************************************************
* Included Files
****************************************************************************/
#include "config.h"
#include <stdint.h>
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#define HWFEAT_CS_INACTIVE (1 << 1) /* Force CS inactive after transfer. */
#define HWFEAT_CS_ACTIVE (1 << 2) /* Force CS active after transfer. */
#define HWFEAT_LSBFIRST (1 << 4) /* 1 for LSB 1st, default 0 for MSB 1st*/
/****************************************************************************
* Public Types
****************************************************************************/
/* The types below (spi_dev_s, spi_ops_s, spi_mode_e, spi_hwfeatures_t and
* spi_mediachange_t) are the same as in nuttx/spi/spi.h.
*/
enum spi_mode_e
{
SPIDEV_MODE0 = 0, /* CPOL=0 CHPHA=0 */
SPIDEV_MODE1, /* CPOL=0 CHPHA=1 */
SPIDEV_MODE2, /* CPOL=1 CHPHA=0 */
SPIDEV_MODE3, /* CPOL=1 CHPHA=1 */
SPIDEV_MODETI, /* CPOL=0 CPHA=1 TI Synchronous Serial Frame Format */
};
#ifdef CONFIG_SPI_HWFEATURES
typedef uint8_t spi_hwfeatures_t;
#endif
typedef void (*spi_mediachange_t)(void *arg);
struct spi_dev_s;
struct spi_ops_s
{
int (*lock)(struct spi_dev_s *dev, bool lock);
void (*select)(struct spi_dev_s *dev, uint32_t devid,
bool selected);
uint32_t (*setfrequency)(struct spi_dev_s *dev,
uint32_t frequency);
#ifdef CONFIG_SPI_CS_DELAY_CONTROL
int (*setdelay)(struct spi_dev_s *dev, uint32_t a,
uint32_t b, uint32_t c);
#endif
void (*setmode)(struct spi_dev_s *dev, enum spi_mode_e mode);
void (*setbits)(struct spi_dev_s *dev, int nbits);
#ifdef CONFIG_SPI_HWFEATURES
int (*hwfeatures)(struct spi_dev_s *dev,
spi_hwfeatures_t features);
#endif
uint8_t (*status)(struct spi_dev_s *dev, uint32_t devid);
#ifdef CONFIG_SPI_CMDDATA
int (*cmddata)(struct spi_dev_s *dev, uint32_t devid,
bool cmd);
#endif
uint32_t (*send)(struct spi_dev_s *dev, uint32_t wd);
#ifdef CONFIG_SPI_EXCHANGE
void (*exchange)(struct spi_dev_s *dev,
const void *txbuffer, void *rxbuffer,
size_t nwords);
#else
void (*sndblock)(struct spi_dev_s *dev,
const void *buffer, size_t nwords);
void (*recvblock)(struct spi_dev_s *dev, void *buffer,
size_t nwords);
#endif
#ifdef CONFIG_SPI_TRIGGER
int (*trigger)(struct spi_dev_s *dev);
#endif
int (*registercallback)(struct spi_dev_s *dev,
spi_mediachange_t callback, void *arg);
};
struct spi_dev_s
{
const struct spi_ops_s *ops;
};
/* NuttX SPI transaction struct (ref: spi_transfer.h). */
struct spi_trans_s
{
/* SPI attributes for unique to this transaction */
bool deselect; /* De-select after transfer */
#ifdef CONFIG_SPI_CMDDATA
bool cmd; /* true=command; false=data */
#endif
#ifdef CONFIG_SPI_HWFEATURES
spi_hwfeatures_t hwfeat; /* H/W features to enable on this transfer */
#endif
useconds_t delay; /* Microsecond delay after transfer */
/* These describe the single data transfer */
size_t nwords; /* Number of words in transfer */
const void *txbuffer; /* Source buffer for TX transfer */
void *rxbuffer; /* Sink buffer for RX transfer */
};
/* NuttX SPI sequence of transactions (ref: spi_transfer.h). */
struct spi_sequence_s
{
/* Properties that are fixed throughout the transfer */
uint32_t dev; /* See enum spi_devtype_e */
uint8_t mode; /* See enum spi_mode_e */
uint8_t nbits; /* Number of bits */
uint8_t ntrans; /* Number of transactions */
uint32_t frequency; /* SPI frequency (Hz) */
#ifdef CONFIG_SPI_CS_DELAY_CONTROL
uint32_t a; /* Arguments to setdelay() */
uint32_t b;
uint32_t c;
#endif
/* A pointer to the list of transfers to be be performed. */
struct spi_trans_s *trans;
};
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
#endif /* _ARCH_SIM_SRC_SIM_SPI_H_ */
File diff suppressed because it is too large Load Diff
+10 -1
View File
@@ -58,7 +58,6 @@ config SIM_WTGAHRS2_UARTN
---help--- ---help---
We can select the number accoding to which SIM_UARTX_NAME is uesd to sensor. We can select the number accoding to which SIM_UARTX_NAME is uesd to sensor.
This range is 0-4. This range is 0-4.
endif
config SIM_I2CBUS_ID config SIM_I2CBUS_ID
int "I2C host bus ID to attach to simulator" int "I2C host bus ID to attach to simulator"
@@ -67,3 +66,13 @@ config SIM_I2CBUS_ID
---help--- ---help---
This is the bus identifier that should be used by the host implementation to This is the bus identifier that should be used by the host implementation to
attach to the simulator driver. attach to the simulator driver.
config SIM_SPIDEV_NAME
string "the name of SPI host dev to attach to simulator"
default "/dev/spidev0.0"
depends on SIM_SPI
---help---
This is the name of the SPI device on the host implementation to
attach to the simulator driver.
endif
@@ -0,0 +1,40 @@
#
# 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_CMDOPT_HEXDUMP is not set
CONFIG_ARCH="sim"
CONFIG_ARCH_BOARD="sim"
CONFIG_ARCH_BOARD_SIM=y
CONFIG_ARCH_CHIP="sim"
CONFIG_ARCH_SIM=y
CONFIG_BOARDCTL_APP_SYMTAB=y
CONFIG_BOARDCTL_POWEROFF=y
CONFIG_BOARDCTL_ROMDISK=y
CONFIG_BOARD_LOOPSPERMSEC=0
CONFIG_BOOT_RUNFROMEXTSRAM=y
CONFIG_BUILTIN=y
CONFIG_DEBUG_SYMBOLS=y
CONFIG_DEV_ZERO=y
CONFIG_EXAMPLES_HELLO=y
CONFIG_FS_PROCFS=y
CONFIG_IDLETHREAD_STACKSIZE=4096
CONFIG_LIBC_EXECFUNCS=y
CONFIG_NSH_ARCHINIT=y
CONFIG_NSH_BUILTIN_APPS=y
CONFIG_NSH_READLINE=y
CONFIG_POSIX_SPAWN_PROXY_STACKSIZE=2048
CONFIG_READLINE_TABCOMPLETION=y
CONFIG_SCHED_HAVE_PARENT=y
CONFIG_SCHED_ONEXIT=y
CONFIG_SCHED_WAITPID=y
CONFIG_SDCLONE_DISABLE=y
CONFIG_SIM_SPI=y
CONFIG_START_MONTH=6
CONFIG_START_YEAR=2008
CONFIG_SYSTEM_NSH=y
CONFIG_SYSTEM_SPITOOL=y
CONFIG_USER_ENTRYPOINT="nsh_main"
+24
View File
@@ -36,6 +36,7 @@
#include <nuttx/fs/nxffs.h> #include <nuttx/fs/nxffs.h>
#include <nuttx/fs/hostfs_rpmsg.h> #include <nuttx/fs/hostfs_rpmsg.h>
#include <nuttx/i2c/i2c_master.h> #include <nuttx/i2c/i2c_master.h>
#include <nuttx/spi/spi_transfer.h>
#include <nuttx/rc/lirc_dev.h> #include <nuttx/rc/lirc_dev.h>
#include <nuttx/rc/dummy.h> #include <nuttx/rc/dummy.h>
#include <nuttx/sensors/fakesensor.h> #include <nuttx/sensors/fakesensor.h>
@@ -101,6 +102,9 @@ int sim_bringup(void)
#ifdef CONFIG_MPU60X0_I2C #ifdef CONFIG_MPU60X0_I2C
FAR struct mpu_config_s *mpu_config; FAR struct mpu_config_s *mpu_config;
#endif #endif
#ifdef CONFIG_SIM_SPI
FAR struct spi_dev_s *spidev;
#endif
int ret = OK; int ret = OK;
@@ -405,6 +409,26 @@ int sim_bringup(void)
#endif #endif
#endif #endif
#ifdef CONFIG_SIM_SPI
spidev = sim_spi_initialize(CONFIG_SIM_SPIDEV_NAME);
if (spidev == NULL)
{
syslog(LOG_ERR, "ERROR: sim_spi_initialize failed.\n");
}
#ifdef CONFIG_SYSTEM_SPITOOL
else
{
ret = spi_register(spidev, 0);
if (ret < 0)
{
syslog(LOG_ERR, "ERROR: Failed to register SPI%d driver: %d\n",
0, ret);
sim_spi_uninitialize(spidev);
}
}
#endif /* CONFIG_SYSTEM_SPITOOL */
#endif /* CONFIG_SIM_SPI */
#if defined(CONFIG_INPUT_BUTTONS_LOWER) && defined(CONFIG_SIM_BUTTONS) #if defined(CONFIG_INPUT_BUTTONS_LOWER) && defined(CONFIG_SIM_BUTTONS)
ret = btn_lower_initialize("/dev/buttons"); ret = btn_lower_initialize("/dev/buttons");
if (ret < 0) if (ret < 0)
+1
View File
@@ -8,6 +8,7 @@
# Do not build Linux configs # Do not build Linux configs
-Darwin,sim:linuxi2c -Darwin,sim:linuxi2c
-Darwin,sim:linuxspi
# macOS doesn't support 32bit(CONFIG_SIM_M32=y) anymore # macOS doesn't support 32bit(CONFIG_SIM_M32=y) anymore
-Darwin,sim:elf -Darwin,sim:elf