From e96673dca7c1ae5a75e716ac697d5bc4071bfc42 Mon Sep 17 00:00:00 2001 From: Andrew Fernandes Date: Sun, 14 Apr 2019 16:14:39 -0700 Subject: [PATCH] drivers: spi: nrfx: allow enabling DMA with the nRF52832 despite PAN 58 Add a Kconfig option to enable DMA for SPI with SOC_NRF52832 as long as it being disabled due to Product Anomaly Notice (PAN) 58 is explicitly overridden. This allows the SPIM driver to be enabled for the nRF52832 SoC for situations where PAN 58 is not a problem. Signed-off-by: Andrew Fernandes --- drivers/spi/Kconfig.nrfx | 34 ++++++++++++++++++------- drivers/spi/spi_nrfx_spim.c | 18 ++++++++++--- soc/arm/nordic_nrf/nrf52/CMakeLists.txt | 8 ++++++ 3 files changed, 47 insertions(+), 13 deletions(-) diff --git a/drivers/spi/Kconfig.nrfx b/drivers/spi/Kconfig.nrfx index 1c7a6b06fc1..34b317d2cd7 100644 --- a/drivers/spi/Kconfig.nrfx +++ b/drivers/spi/Kconfig.nrfx @@ -14,6 +14,19 @@ menuconfig SPI_NRFX if SPI_NRFX +config SOC_NRF52832_ALLOW_SPIM_DESPITE_PAN_58 + depends on SOC_NRF52832 + bool "Allow enabling the SPIM driver despite PAN 58" + help + Allow enabling the nRF SPI Master with EasyDMA, despite + Product Anomaly Notice 58 (SPIM: An additional byte is + clocked out when RXD.MAXCNT == 1 and TXD.MAXCNT <= 1). + Without this override, the SPI Master is only available + without EasyDMA. Note that the 'SPIM' and 'SPIS' drivers + use EasyDMA, while the 'SPI' driver does not. Use this + option ONLY if you are certain that transactions with + RXD.MAXCNT == 1 and TXD.MAXCNT <= 1 will NOT be executed. + # In most Nordic SoCs, SPI and TWI peripherals with the same instance number # share certain resources and therefore cannot be used at the same time # (in nRF91 Series this limitation concerns UART peripherals as well). @@ -34,9 +47,10 @@ config SPI_0_NRF_SPI config SPI_0_NRF_SPIM bool "nRF SPIM 0" - # This driver is not available for nRF52832 because of the anomaly 58 - # (SPIM: An additional byte is clocked out when RXD.MAXCNT = 1). - depends on HAS_HW_NRF_SPIM0 && !SOC_NRF52832 + # This driver is not available for nRF52832 because of Product Anomaly 58 + # (SPIM: An additional byte is clocked out when RXD.MAXCNT == 1 and TXD.MAXCNT <= 1) + # Allow the 'EasyDMA' driver only if this automatic safety-disable is overridden + depends on HAS_HW_NRF_SPIM0 && (!SOC_NRF52832 || SOC_NRF52832_ALLOW_SPIM_DESPITE_PAN_58) select NRFX_SPIM help Enable nRF SPI Master with EasyDMA on port 0. @@ -84,9 +98,10 @@ config SPI_1_NRF_SPI config SPI_1_NRF_SPIM bool "nRF SPIM 1" - # This driver is not available for nRF52832 because of the anomaly 58 - # (SPIM: An additional byte is clocked out when RXD.MAXCNT = 1). - depends on HAS_HW_NRF_SPIM1 && !SOC_NRF52832 + # This driver is not available for nRF52832 because of Product Anomaly 58 + # (SPIM: An additional byte is clocked out when RXD.MAXCNT == 1 and TXD.MAXCNT <= 1) + # Allow the 'EasyDMA' driver only if this automatic safety-disable is overridden + depends on HAS_HW_NRF_SPIM1 && (!SOC_NRF52832 || SOC_NRF52832_ALLOW_SPIM_DESPITE_PAN_58) select NRFX_SPIM help Enable nRF SPI Master with EasyDMA on port 1. @@ -134,9 +149,10 @@ config SPI_2_NRF_SPI config SPI_2_NRF_SPIM bool "nRF SPIM 2" - # This driver is not available for nRF52832 because of the anomaly 58 - # (SPIM: An additional byte is clocked out when RXD.MAXCNT = 1). - depends on HAS_HW_NRF_SPIM2 && !SOC_NRF52832 + # This driver is not available for nRF52832 because of Product Anomaly 58 + # (SPIM: An additional byte is clocked out when RXD.MAXCNT == 1 and TXD.MAXCNT <= 1) + # Allow the 'EasyDMA' driver only if this automatic safety-disable is overridden + depends on HAS_HW_NRF_SPIM2 && (!SOC_NRF52832 || SOC_NRF52832_ALLOW_SPIM_DESPITE_PAN_58) select NRFX_SPIM help Enable nRF SPI Master with EasyDMA on port 2. diff --git a/drivers/spi/spi_nrfx_spim.c b/drivers/spi/spi_nrfx_spim.c index e0af53e2fab..c2eb3262625 100644 --- a/drivers/spi/spi_nrfx_spim.c +++ b/drivers/spi/spi_nrfx_spim.c @@ -178,12 +178,22 @@ static void transfer_next_chunk(struct device *dev) xfer.tx_length = spi_context_tx_buf_on(ctx) ? chunk_len : 0; xfer.p_rx_buffer = ctx->rx_buf; xfer.rx_length = spi_context_rx_buf_on(ctx) ? chunk_len : 0; - result = nrfx_spim_xfer(&dev_config->spim, &xfer, 0); - if (result == NRFX_SUCCESS) { - return; + + /* This SPIM driver is only used by the NRF52832 if + SOC_NRF52832_ALLOW_SPIM_DESPITE_PAN_58 is enabled */ + if (IS_ENABLED(CONFIG_SOC_NRF52832) && + (xfer.rx_length == 1 && xfer.tx_length <= 1)) { + LOG_WRN("Transaction aborted since it would trigger nRF52832 PAN 58"); + error = -EIO; } - error = -EIO; + if (!error) { + result = nrfx_spim_xfer(&dev_config->spim, &xfer, 0); + if (result == NRFX_SUCCESS) { + return; + } + error = -EIO; + } } spi_context_cs_control(ctx, false); diff --git a/soc/arm/nordic_nrf/nrf52/CMakeLists.txt b/soc/arm/nordic_nrf/nrf52/CMakeLists.txt index e08acdf9980..05b428fec81 100644 --- a/soc/arm/nordic_nrf/nrf52/CMakeLists.txt +++ b/soc/arm/nordic_nrf/nrf52/CMakeLists.txt @@ -11,3 +11,11 @@ zephyr_sources_ifdef(CONFIG_SYS_POWER_MANAGEMENT zephyr_sources_ifdef(CONFIG_ARM_MPU mpu_regions.c ) + +if(CONFIG_SOC_NRF52832) + if(CONFIG_SOC_NRF52832_ALLOW_SPIM_DESPITE_PAN_58) + if(CONFIG_SPI_0_NRF_SPIM or CONFIG_SPI_1_NRF_SPIM or CONFIG_SPI_2_NRF_SPIM) + message(WARNING "Both SOC_NRF52832_ALLOW_SPIM_DESPITE_PAN_58 and an NRF SPIM driver are enabled, therefore PAN 58 will apply if RXD.MAXCNT == 1 and TXD.MAXCNT <= 1") + endif() + endif() +endif()