Added registering logic SPI on /dev.

This commit is contained in:
John Bonham 2022-02-25 12:21:29 +03:00 committed by Xiang Xiao
parent ea1b49119a
commit 7c99bce16e
5 changed files with 288 additions and 29 deletions

View File

@ -44,6 +44,10 @@ ifeq ($(CONFIG_MMCSD_SPI),y)
CSRCS += stm32_spisd.c
endif
ifeq ($(CONFIG_STM32_SPI),y)
CSRCS += stm32_spi.c
endif
DEPPATH += --dep-path board
VPATH += :board
CFLAGS += $(shell $(INCDIR) "$(CC)" $(TOPDIR)$(DELIM)arch$(DELIM)$(CONFIG_ARCH)$(DELIM)src$(DELIM)board$(DELIM)board)

View File

@ -116,3 +116,17 @@ int stm32_spisd_initialize(int port, int minor);
#endif
#endif /* CONFIG_FS_PROCFS */
#endif /* __BOARDS_ARM_STM32_NUCLEO_L152RE_SRC_NUCLEO_L152RE_H */
/****************************************************************************
* Public Functions Definitions
****************************************************************************/
/****************************************************************************
* Name: stm32_spiinitialize
*
* Description:
* Called to configure SPI chip select GPIO pins.
*
****************************************************************************/
void stm32_spiinitialize(void);

View File

@ -130,6 +130,10 @@ int board_app_initialize(uintptr_t arg)
}
#endif
#ifdef CONFIG_STM32_SPI
stm32_spiinitialize();
#endif
#ifdef HAVE_LEDS
/* Register the LED driver */

View File

@ -0,0 +1,266 @@
/****************************************************************************
* boards/arm/stm32/nucleo-l152re/src/stm32_spi.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 <debug.h>
#include <sys/types.h>
#include <syslog.h>
#include <arch/board/board.h>
#include <nuttx/spi/spi.h>
#include <nuttx/spi/spi_transfer.h>
#include "arm_arch.h"
#include "chip.h"
#include "stm32_gpio.h"
#include "stm32_spi.h"
#include "nucleo-l152re.h"
#if defined(CONFIG_STM32_SPI1) || defined(CONFIG_STM32_SPI2) || defined(CONFIG_STM32_SPI3)
/****************************************************************************
* Public Data
****************************************************************************/
/* Global driver instances */
#ifdef CONFIG_STM32_SPI1
FAR struct spi_dev_s *g_spi1;
#endif
#ifdef CONFIG_STM32_SPI2
FAR struct spi_dev_s *g_spi2;
#endif
#ifdef CONFIG_STM32_SPI3
FAR struct spi_dev_s *g_spi3;
#endif
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: stm32_spiinitialize
*
* Description:
* Called to configure SPI chip select GPIO pins.
*
****************************************************************************/
void weak_function stm32_spiinitialize(void)
{
int ret;
#ifdef CONFIG_STM32_SPI1
/* Initialize the SPI1 bus */
g_spi1 = stm32_spibus_initialize(1);
if (g_spi1 == NULL)
{
spierr("ERROR: Initialize SPI1: \n");
}
#ifdef CONFIG_SPI_DRIVER
/* Register the SPI1 character driver */
ret = spi_register(g_spi1, 1);
if (ret < 0)
{
spierr("ERROR: Failed to register SPI1 device: %d\n", ret);
}
#endif
#endif
#ifdef CONFIG_STM32_SPI2
/* Initialize the SPI2 bus */
g_spi2 = stm32_spibus_initialize(2);
if (g_spi2 == NULL)
{
spierr("ERROR: Initialize SPI2: \n");
}
#ifdef CONFIG_SPI_DRIVER
/* Register the SPI2 character driver */
ret = spi_register(g_spi2, 2);
if (ret < 0)
{
spierr("ERROR: Failed to register SPI2 device: %d\n", ret);
}
#endif
#endif
#ifdef CONFIG_STM32_SPI3
/* Initialize the SPI3 bus */
g_spi3 = stm32_spibus_initialize(3);
if (g_spi3 == NULL)
{
spierr("ERROR: Initialize SPI3: \n");
}
#ifdef CONFIG_SPI_DRIVER
/* Register the SPI3 character driver */
ret = spi_register(g_spi3, 3);
if (ret < 0)
{
spierr("ERROR: Failed to register SPI3 device: %d\n", ret);
}
#endif
#endif
}
/****************************************************************************
* Name: stm32_spi1/2/3select and stm32_spi1/2/3status
*
* Description:
* The external functions, stm32_spi1/2/3select and stm32_spi1/2/3status
* must be provided by board-specific logic. They are implementations of
* the select and status methods of the SPI interface defined by struct
* spi_ops_s (see include/nuttx/spi/spi.h). All other methods (including
* stm32_spibus_initialize()) are provided by common STM32 logic. To use
* this common SPI logic on your board:
*
* 1. Provide logic in stm32_boardinitialize() to configure SPI chip select
* pins.
* 2. Provide stm32_spi1/2/3select() and stm32_spi1/2/3status() functions
* in your board-specific logic. These functions will perform chip
* selection and status operations using GPIOs in the way your board
* is configured.
* 3. Add a calls to stm32_spibus_initialize() in your low level
* application initialization logic
* 4. The handle returned by stm32_spibus_initialize() may then be used to
* bind the SPI driver to higher level logic (e.g., calling
* mmcsd_spislotinitialize(), for example, will bind the SPI driver to
* the SPI MMC/SD driver).
*
****************************************************************************/
#ifdef CONFIG_STM32_SPI1
void stm32_spi1select(FAR struct spi_dev_s *dev, uint32_t devid,
bool selected)
{
spiinfo("devid: %d CS: %s\n", (int)devid, selected ? "assert" :
"de-assert");
#if defined(CONFIG_MMCSD_SPI)
if (devid == SPIDEV_MMCSD(0))
{
stm32_gpiowrite(GPIO_SPI1_CS, !selected);
}
#endif
}
uint8_t stm32_spi1status(FAR struct spi_dev_s *dev, uint32_t devid)
{
uint8_t status = 0;
#if defined(CONFIG_MMCSD_SPI)
if (devid == SPIDEV_MMCSD(0))
{
status |= SPI_STATUS_PRESENT;
}
#endif
return status;
}
#endif
#ifdef CONFIG_STM32_SPI2
void stm32_spi2select(FAR struct spi_dev_s *dev, uint32_t devid,
bool selected)
{
spiinfo("devid: %d CS: %s\n", (int)devid, selected ? "assert" :
"de-assert");
}
uint8_t stm32_spi2status(FAR struct spi_dev_s *dev, uint32_t devid)
{
return 0;
}
#endif
#ifdef CONFIG_STM32_SPI3
void stm32_spi3select(FAR struct spi_dev_s *dev, uint32_t devid,
bool selected)
{
spiinfo("devid: %d CS: %s\n", (int)devid, selected ? "assert" :
"de-assert");
}
uint8_t stm32_spi3status(FAR struct spi_dev_s *dev, uint32_t devid)
{
return 0;
}
#endif
/****************************************************************************
* Name: stm32_spi1cmddata
*
* Description:
* Set or clear the SH1101A A0 or SD1306 D/C n bit to select data (true)
* or command (false). This function must be provided by platform-specific
* logic. This is an implementation of the cmddata method of the SPI
* interface defined by struct spi_ops_s (see include/nuttx/spi/spi.h).
*
* Input Parameters:
*
* spi - SPI device that controls the bus the device that requires the CMD/
* DATA selection.
* devid - If there are multiple devices on the bus, this selects which one
* to select cmd or data. NOTE: This design restricts, for example,
* one one SPI display per SPI bus.
* cmd - true: select command; false: select data
*
* Returned Value:
* None
*
****************************************************************************/
#ifdef CONFIG_SPI_CMDDATA
#ifdef CONFIG_STM32_SPI1
int stm32_spi1cmddata(FAR struct spi_dev_s *dev, uint32_t devid, bool cmd)
{
return -ENODEV;
}
#endif
#ifdef CONFIG_STM32_SPI2
int stm32_spi2cmddata(FAR struct spi_dev_s *dev, uint32_t devid, bool cmd)
{
return -ENODEV;
}
#endif
#ifdef CONFIG_STM32_SPI3
int stm32_spi3cmddata(FAR struct spi_dev_s *dev, uint32_t devid, bool cmd)
{
return -ENODEV;
}
#endif
#endif /* CONFIG_SPI_CMDDATA */
#endif /* CONFIG_STM32_SPI1 || CONFIG_STM32_SPI2 || CONFIG_STM32_SPI3 */

View File

@ -69,35 +69,6 @@ int stm32_spi1register(struct spi_dev_s *dev, spi_mediachange_t callback,
return OK;
}
void stm32_spi1select(FAR struct spi_dev_s *dev, uint32_t devid,
bool selected)
{
spiinfo("devid: %d CS: %s\n", (int)devid, selected ? "assert" :
"de-assert");
#if defined(CONFIG_MMCSD_SPI)
stm32_gpiowrite(GPIO_SPI1_CS, !selected);
#endif
}
uint8_t stm32_spi1status(FAR struct spi_dev_s *dev, uint32_t devid)
{
uint8_t ret = 0;
#if defined(CONFIG_MMCSD_SPI)
if (devid == SPIDEV_MMCSD(0))
{
ret |= SPI_STATUS_PRESENT;
}
#endif
return ret;
}
int stm32_spi1cmddata(FAR struct spi_dev_s *dev, uint32_t devid,
bool cmd)
{
return -ENODEV;
}
/****************************************************************************
* Name: stm32_spisd_initialize
*