nxp_fmurt1170-v1:Proper SPI usage

This commit is contained in:
David Sidrane
2023-06-17 00:54:17 -07:00
parent 1cc4e8dd65
commit 0df41968d0
7 changed files with 591 additions and 316 deletions
@@ -61,6 +61,7 @@ px4_add_library(drivers_board
target_link_libraries(drivers_board
PRIVATE
arch_board_hw_info
arch_spi
drivers__led # drv_led_start
nuttx_arch # sdio
nuttx_drivers # sdio
+11 -20
View File
@@ -600,26 +600,6 @@ __BEGIN_DECLS
int fmurt1170_usdhc_initialize(void);
/****************************************************************************************************
* Name: imxrt_spidev_initialize
*
* Description:
* Called to configure SPI chip select GPIO pins for the PX4FMU board.
*
****************************************************************************************************/
extern void imxrt_spidev_initialize(void);
/************************************************************************************
* Name: imxrt_spi_bus_initialize
*
* Description:
* Called to configure SPI Buses.
*
************************************************************************************/
extern int imxrt1176_spi_bus_initialize(void);
/************************************************************************************
* Name: imxrt_usb_initialize
*
@@ -630,6 +610,17 @@ extern int imxrt1176_spi_bus_initialize(void);
extern int imxrt_usb_initialize(void);
/****************************************************************************************************
* Name: nxp_spiinitialize
*
* Description:
* Called to configure SPI chip select GPIO pins for the PX4FMU board.
*
****************************************************************************************************/
extern void imxrt_spiinitialize(void);
extern void imxrt_usbinitialize(void);
extern void board_peripheral_reset(int ms);
+17 -6
View File
@@ -211,10 +211,6 @@ __EXPORT void imxrt_boardinitialize(void)
const uint32_t gpio[] = PX4_GPIO_INIT_LIST;
px4_gpio_init(gpio, arraySize(gpio));
/* configure SPI interfaces */
imxrt_spidev_initialize();
imxrt_usb_initialize();
fmurt107x_timer_initialize();
@@ -251,7 +247,17 @@ __EXPORT int board_app_initialize(uintptr_t arg)
int ret = OK;
board_spi_reset(10, 0xffff);
/* Need hrt running before using the ADC */
px4_platform_init();
// Use the default HW_VER_REV(0x0,0x0) for Ramtron
imxrt_spiinitialize();
/* Configure the HW based on the manifest */
px4_platform_configure();
if (OK == board_determine_hw_info()) {
syslog(LOG_INFO, "[boot] Rev 0x%1x : Ver 0x%1x %s\n", board_get_hw_revision(), board_get_hw_version(),
@@ -261,7 +267,12 @@ __EXPORT int board_app_initialize(uintptr_t arg)
syslog(LOG_ERR, "[boot] Failed to read HW revision and version\n");
}
px4_platform_init();
/* Configure the Actual SPI interfaces (after we determined the HW version) */
imxrt_spiinitialize();
board_spi_reset(10, 0xffff);
/* configure the DMA allocator */
+1 -290
View File
@@ -83,294 +83,5 @@ constexpr px4_spi_bus_t px4_spi_buses[SPI_BUS_MAX_BUS_ITEMS] = {
}),
};
#endif
static constexpr bool unused = validateSPIConfig(px4_spi_buses);
//#define _PIN_OFF(def) (((def) & (GPIO_PORT_MASK | GPIO_PIN_MASK)) | (GPIO_INPUT | IOMUX_PULL_DOWN_100K | IOMUX_CMOS_INPUT))
/************************************************************************************
* Public Functions
************************************************************************************/
/************************************************************************************
* Name: fmurt1170_spidev_initialize
*
* Description:
* Called to configure SPI chip select GPIO pins for the NXP FMUKRT1170-V1 board.
*
************************************************************************************/
void imxrt_spidev_initialize(void)
{
for (int bus = 0; bus < SPI_BUS_MAX_BUS_ITEMS; ++bus) {
for (int i = 0; i < SPI_BUS_MAX_DEVICES; ++i) {
if (px4_spi_buses[bus].devices[i].cs_gpio != 0) {
px4_arch_configgpio(px4_spi_buses[bus].devices[i].cs_gpio);
}
}
}
}
/************************************************************************************
* Name: imxrt_spi_bus_initialize
*
* Description:
* Called to configure SPI chip select GPIO pins for the NXP FMUKRT1170-V1 board.
*
************************************************************************************/
static const px4_spi_bus_t *_spi_bus1;
static const px4_spi_bus_t *_spi_bus2;
static const px4_spi_bus_t *_spi_bus3;
static const px4_spi_bus_t *_spi_bus6;
__EXPORT int imxrt1176_spi_bus_initialize(void)
{
for (int i = 0; i < SPI_BUS_MAX_BUS_ITEMS; ++i) {
switch (px4_spi_buses[i].bus) {
case 1: _spi_bus1 = &px4_spi_buses[i]; break;
case 6: _spi_bus6 = &px4_spi_buses[i]; break;
}
}
/* Configure SPI-based devices */
struct spi_dev_s *spi_sensors = px4_spibus_initialize(1);
if (!spi_sensors) {
PX4_ERR("[boot] FAILED to initialize SPI port %d\n", 1);
return -ENODEV;
}
/* Default bus 1 to 1MHz and de-assert the known chip selects.
*/
SPI_SETFREQUENCY(spi_sensors, 1 * 1000 * 1000);
SPI_SETBITS(spi_sensors, 8);
SPI_SETMODE(spi_sensors, SPIDEV_MODE3);
/* Get the SPI port for the Memory */
struct spi_dev_s *spi_memory = px4_spibus_initialize(6);
if (!spi_memory) {
PX4_ERR("[boot] FAILED to initialize SPI port %d\n", 2);
return -ENODEV;
}
/* Default PX4_SPI_BUS_MEMORY to 12MHz and de-assert the known chip selects.
*/
SPI_SETFREQUENCY(spi_memory, 12 * 1000 * 1000);
SPI_SETBITS(spi_memory, 8);
SPI_SETMODE(spi_memory, SPIDEV_MODE3);
/* deselect all */
for (int bus = 0; bus < SPI_BUS_MAX_BUS_ITEMS; ++bus) {
for (int i = 0; i < SPI_BUS_MAX_DEVICES; ++i) {
if (px4_spi_buses[bus].devices[i].cs_gpio != 0) {
//SPI_SELECT(spi_ext, px4_spi_buses[bus].devices[i].devid, false);
}
}
}
return OK;
}
/****************************************************************************
* Name: imxrt_lpspi1/2/3select and imxrt_lpspi1/2/3status
*
* Description:
* The external functions, imxrt_lpspi1/2/3select and imxrt_lpspi1/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 imxrt_lpspibus_initialize())
* are provided by common STM32 logic. To use this common SPI logic on your
* board:
*
* 1. Provide logic in imxrt_boardinitialize() to configure SPI chip select
* pins.
* 2. Provide imxrt_lpspi1/2/3select() and imxrt_lpspi1/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 imxrt_lpspibus_initialize() in your low level application
* initialization logic
* 4. The handle returned by imxrt_lpspibus_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).
*
****************************************************************************/
static inline void imxrt_spixselect(const px4_spi_bus_t *bus, struct spi_dev_s *dev, uint32_t devid, bool selected)
{
for (int i = 0; i < SPI_BUS_MAX_DEVICES; ++i) {
if (bus->devices[i].cs_gpio == 0) {
break;
}
if (devid == bus->devices[i].devid) {
// SPI select is active low, so write !selected to select the device
imxrt_gpio_write(bus->devices[i].cs_gpio, !selected);
}
}
}
#if defined(CONFIG_IMXRT_LPSPI1)
__EXPORT void imxrt_lpspi1select(FAR struct spi_dev_s *dev, uint32_t devid, bool selected)
{
imxrt_spixselect(_spi_bus1, dev, devid, selected);
}
__EXPORT uint8_t imxrt_lpspi1status(FAR struct spi_dev_s *dev, uint32_t devid)
{
return SPI_STATUS_PRESENT;
}
#endif
#if defined(CONFIG_IMXRT_LPSPI2)
__EXPORT void imxrt_lpspi2select(FAR struct spi_dev_s *dev, uint32_t devid, bool selected)
{
imxrt_spixselect(_spi_bus2, dev, devid, selected);
}
__EXPORT uint8_t imxrt_lpspi2status(FAR struct spi_dev_s *dev, uint32_t devid)
{
return SPI_STATUS_PRESENT;
}
#endif
#if defined(CONFIG_IMXRT_LPSPI3)
__EXPORT void imxrt_lpspi3select(FAR struct spi_dev_s *dev, uint32_t devid, bool selected)
{
imxrt_spixselect(_spi_bus3, dev, devid, selected);
}
__EXPORT uint8_t imxrt_lpspi3status(FAR struct spi_dev_s *dev, uint32_t devid)
{
return SPI_STATUS_PRESENT;
}
#endif
#if defined(CONFIG_IMXRT_LPSPI4)
__EXPORT void imxrt_lpspi4select(FAR struct spi_dev_s *dev, uint32_t devid, bool selected)
{
imxrt_spixselect(_spi_bus4, dev, devid, selected);
}
__EXPORT uint8_t imxrt_lpspi4status(FAR struct spi_dev_s *dev, uint32_t devid)
{
return SPI_STATUS_PRESENT;
}
#endif
#if defined(CONFIG_IMXRT_LPSPI5)
__EXPORT void imxrt_lpspi5select(FAR struct spi_dev_s *dev, uint32_t devid, bool selected)
{
imxrt_spixselect(_spi_bus5, dev, devid, selected);
}
__EXPORT uint8_t imxrt_lpspi5status(FAR struct spi_dev_s *dev, uint32_t devid)
{
return SPI_STATUS_PRESENT;
}
#endif
#if defined(CONFIG_IMXRT_LPSPI6)
__EXPORT void imxrt_lpspi6select(FAR struct spi_dev_s *dev, uint32_t devid, bool selected)
{
imxrt_spixselect(_spi_bus6, dev, devid, selected);
}
__EXPORT uint8_t imxrt_lpspi6status(FAR struct spi_dev_s *dev, uint32_t devid)
{
return SPI_STATUS_PRESENT;
}
#endif
/************************************************************************************
* Name: board_spi_reset
*
* Description:
*
*
************************************************************************************/
__EXPORT void board_spi_reset(int ms, int bus_mask)
{
#ifdef CONFIG_IMXRT_LPSPI1
/* Goal not to back feed the chips on the bus via IO lines */
for (int bus = 0; bus < SPI_BUS_MAX_BUS_ITEMS; ++bus) {
if (px4_spi_buses[bus].bus == 1 || px4_spi_buses[bus].bus == 3) {
for (int i = 0; i < SPI_BUS_MAX_DEVICES; ++i) {
if (px4_spi_buses[bus].devices[i].cs_gpio != 0) {
imxrt_config_gpio(_PIN_OFF(px4_spi_buses[bus].devices[i].cs_gpio));
}
if (px4_spi_buses[bus].devices[i].drdy_gpio != 0) {
imxrt_config_gpio(_PIN_OFF(px4_spi_buses[bus].devices[i].drdy_gpio));
}
}
}
}
imxrt_config_gpio(GPIO_SPI1_SCK_OFF);
imxrt_config_gpio(GPIO_SPI1_MISO_OFF);
imxrt_config_gpio(GPIO_SPI1_MOSI_OFF);
imxrt_config_gpio(GPIO_SPI3_SCK_OFF);
imxrt_config_gpio(GPIO_SPI3_MISO_OFF);
imxrt_config_gpio(GPIO_SPI3_MOSI_OFF);
//imxrt_config_gpio(_PIN_OFF(GPIO_LPI2C3_SDA_RESET));
//imxrt_config_gpio(_PIN_OFF(GPIO_LPI2C3_SCL_RESET));
/* set the sensor rail off */
//imxrt_gpio_write(GPIO_VDD_3V3_SENSORS_EN, 0);
/* wait for the sensor rail to reach GND */
usleep(ms * 1000);
warnx("reset done, %d ms", ms);
/* re-enable power */
/* switch the sensor rail back on */
//imxrt_gpio_write(GPIO_VDD_3V3_SENSORS_EN, 1);
/* wait a bit before starting SPI, different times didn't influence results */
usleep(100);
/* reconfigure the SPI pins */
for (int bus = 0; bus < SPI_BUS_MAX_BUS_ITEMS; ++bus) {
if (px4_spi_buses[bus].bus == 1 || px4_spi_buses[bus].bus == 3) {
for (int i = 0; i < SPI_BUS_MAX_DEVICES; ++i) {
if (px4_spi_buses[bus].devices[i].cs_gpio != 0) {
imxrt_config_gpio(px4_spi_buses[bus].devices[i].cs_gpio);
}
if (px4_spi_buses[bus].devices[i].drdy_gpio != 0) {
imxrt_config_gpio(px4_spi_buses[bus].devices[i].drdy_gpio);
}
}
}
}
imxrt_config_gpio(GPIO_LPSPI1_SCK);
imxrt_config_gpio(GPIO_LPSPI1_MISO);
imxrt_config_gpio(GPIO_LPSPI1_MOSI);
//imxrt_config_gpio(GPIO_LPSPI3_SCK);
//imxrt_config_gpio(GPIO_LPSPI3_MISO);
//imxrt_config_gpio(GPIO_LPSPI3_MOSI);
//imxrt_config_gpio(GPIO_LPI2C3_SDA);
//imxrt_config_gpio(GPIO_LPI2C3_SCL);
#endif /* CONFIG_IMXRT_LPSPI */
}
#endif /* CONFIG_IMXRT_LPSPI */