Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions drivers/flash/nrf_qspi_nor.c
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ BUILD_ASSERT(INST_0_SCK_FREQUENCY >= (NRF_QSPI_BASE_CLOCK_FREQ / 16),
#define BASE_CLOCK_DIV NRF_CLOCK_HFCLK_DIV_1
#define INST_0_SCK_CFG NRF_QSPI_FREQ_DIV1
/* If anomaly 159 is to be prevented, only /1 divider can be used. */
#elif NRF53_ERRATA_159_ENABLE_WORKAROUND
#elif NRF_ERRATA_STATIC_CHECK(53, 159)
#define BASE_CLOCK_DIV NRF_CLOCK_HFCLK_DIV_1
#define INST_0_SCK_CFG (DIV_ROUND_UP(NRF_QSPI_BASE_CLOCK_FREQ, \
INST_0_SCK_FREQUENCY) - 1)
Expand Down Expand Up @@ -251,7 +251,7 @@ static inline int qspi_get_zephyr_ret_code(nrfx_err_t res)
return -EINVAL;
case NRFX_ERROR_INVALID_STATE:
return -ECANCELED;
#if NRF53_ERRATA_159_ENABLE_WORKAROUND
#if NRF_ERRATA_STATIC_CHECK(53, 159)
case NRFX_ERROR_FORBIDDEN:
LOG_ERR("nRF5340 anomaly 159 conditions detected");
LOG_ERR("Set the CPU clock to 64 MHz before starting QSPI operation");
Expand Down
4 changes: 2 additions & 2 deletions drivers/flash/soc_flash_nrf.c
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ static inline bool is_uicr_addr_valid(off_t addr, size_t len)
#endif /* CONFIG_SOC_FLASH_NRF_UICR */
}

#if CONFIG_SOC_FLASH_NRF_UICR && IS_ENABLED(NRF91_ERRATA_7_ENABLE_WORKAROUND)
#if CONFIG_SOC_FLASH_NRF_UICR && NRF_ERRATA_STATIC_CHECK(91, 7)
static inline void nrf91_errata_7_enter(void)
{
__disable_irq();
Expand Down Expand Up @@ -164,7 +164,7 @@ static int flash_nrf_read(const struct device *dev, off_t addr,
return 0;
}

#if CONFIG_SOC_FLASH_NRF_UICR && IS_ENABLED(NRF91_ERRATA_7_ENABLE_WORKAROUND)
#if CONFIG_SOC_FLASH_NRF_UICR && NRF_ERRATA_STATIC_CHECK(91, 7)
if (within_uicr) {
nrf_buffer_read_91_uicr(data, (uint32_t)addr, len);
return 0;
Expand Down
5 changes: 1 addition & 4 deletions drivers/pwm/pwm_nrfx.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,7 @@

LOG_MODULE_REGISTER(pwm_nrfx, CONFIG_PWM_LOG_LEVEL);

/* NRFX_PWM_NRF52_ANOMALY_109_WORKAROUND_ENABLED can be undefined or defined
* to 0 or 1, hence the use of #if IS_ENABLED().
*/
#if IS_ENABLED(NRFX_PWM_NRF52_ANOMALY_109_WORKAROUND_ENABLED)
#if NRF_ERRATA_STATIC_CHECK(52, 109)
#define ANOMALY_109_EGU_IRQ_CONNECT(idx) _EGU_IRQ_CONNECT(idx)
#define _EGU_IRQ_CONNECT(idx) \
extern void nrfx_egu_##idx##_irq_handler(void); \
Expand Down
18 changes: 0 additions & 18 deletions drivers/spi/Kconfig.nrfx
Original file line number Diff line number Diff line change
Expand Up @@ -72,24 +72,6 @@ config SPI_NRFX_SPIS
select NRFX_SPIS136 if HAS_HW_NRF_SPIS136
select NRFX_SPIS137 if HAS_HW_NRF_SPIS137

config SOC_NRF52832_ALLOW_SPIM_DESPITE_PAN_58
depends on SOC_NRF52832
select NRFX_PPI
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.
When used in conjunction with nRF SPIM Devicetree property
'anomaly-58-workaround' a workaround can be enabled per SPIM
instance. If you are certain that transactions with
RXD.MAXCNT == 1 and TXD.MAXCNT <= 1 will NOT be executed
then nRF52832 PPI and GPIOTE resources can be saved by not
enabling 'anomaly-58-workaround' via the Devicetree.

config SPI_NRFX_RAM_BUFFER_SIZE
int "Size of RAM buffers for SPIM peripherals"
default 8
Expand Down
140 changes: 3 additions & 137 deletions drivers/spi/spi_nrfx_spim.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,6 @@
#include <zephyr/mem_mgmt/mem_attr.h>
#include <soc.h>
#include <dmm.h>
#ifdef CONFIG_SOC_NRF52832_ALLOW_SPIM_DESPITE_PAN_58
#include <nrfx_ppi.h>
#endif
#ifdef CONFIG_SOC_NRF5340_CPUAPP
#include <hal/nrf_clock.h>
#endif
Expand All @@ -31,12 +28,6 @@ LOG_MODULE_REGISTER(spi_nrfx_spim, CONFIG_SPI_LOG_LEVEL);
#include "spi_context.h"
#include "spi_nrfx_common.h"

#if defined(CONFIG_SOC_NRF52832) && !defined(CONFIG_SOC_NRF52832_ALLOW_SPIM_DESPITE_PAN_58)
#error This driver is not available by default for nRF52832 because of Product Anomaly 58 \
(SPIM: An additional byte is clocked out when RXD.MAXCNT == 1 and TXD.MAXCNT <= 1). \
Use CONFIG_SOC_NRF52832_ALLOW_SPIM_DESPITE_PAN_58=y to override this limitation.
#endif

#if (CONFIG_SPI_NRFX_RAM_BUFFER_SIZE > 0)
#define SPI_BUFFER_IN_RAM 1
#endif
Expand Down Expand Up @@ -112,11 +103,6 @@ struct spi_nrfx_data {
uint8_t *tx_buffer;
uint8_t *rx_buffer;
#endif
#ifdef CONFIG_SOC_NRF52832_ALLOW_SPIM_DESPITE_PAN_58
bool anomaly_58_workaround_active;
uint8_t ppi_ch;
uint8_t gpiote_ch;
#endif
#ifdef SPIM_ANY_FAST
bool clock_requested;
#endif
Expand All @@ -129,9 +115,6 @@ struct spi_nrfx_config {
void (*irq_connect)(void);
uint16_t max_chunk_len;
const struct pinctrl_dev_config *pcfg;
#ifdef CONFIG_SOC_NRF52832_ALLOW_SPIM_DESPITE_PAN_58
bool anomaly_58_workaround;
#endif
uint32_t wake_pin;
nrfx_gpiote_t wake_gpiote;
#ifdef SPIM_ANY_FAST
Expand Down Expand Up @@ -384,89 +367,6 @@ static int configure(const struct device *dev,
return 0;
}

#ifdef CONFIG_SOC_NRF52832_ALLOW_SPIM_DESPITE_PAN_58
static const nrfx_gpiote_t gpiote = NRFX_GPIOTE_INSTANCE(0);

/*
* Brief Workaround for transmitting 1 byte with SPIM.
*
* Derived from the setup_workaround_for_ftpan_58() function from
* the nRF52832 Rev 1 Errata v1.6 document anomaly 58 workaround.
*
* Warning Must not be used when transmitting multiple bytes.
*
* Warning After this workaround is used, the user must reset the PPI
* channel and the GPIOTE channel before attempting to transmit multiple
* bytes.
*/
static void anomaly_58_workaround_setup(const struct device *dev)
{
struct spi_nrfx_data *dev_data = dev->data;
const struct spi_nrfx_config *dev_config = dev->config;
NRF_SPIM_Type *spim = dev_config->spim.p_reg;
uint32_t ppi_ch = dev_data->ppi_ch;
uint32_t gpiote_ch = dev_data->gpiote_ch;
uint32_t eep = (uint32_t)&gpiote.p_reg->EVENTS_IN[gpiote_ch];
uint32_t tep = (uint32_t)&spim->TASKS_STOP;

dev_data->anomaly_58_workaround_active = true;

/* Create an event when SCK toggles */
nrf_gpiote_event_configure(gpiote.p_reg, gpiote_ch, spim->PSEL.SCK,
GPIOTE_CONFIG_POLARITY_Toggle);
nrf_gpiote_event_enable(gpiote.p_reg, gpiote_ch);

/* Stop the spim instance when SCK toggles */
nrf_ppi_channel_endpoint_setup(NRF_PPI, ppi_ch, eep, tep);
nrf_ppi_channel_enable(NRF_PPI, ppi_ch);

/* The spim instance cannot be stopped mid-byte, so it will finish
* transmitting the first byte and then stop. Effectively ensuring
* that only 1 byte is transmitted.
*/
}

static void anomaly_58_workaround_clear(struct spi_nrfx_data *dev_data)
{
uint32_t ppi_ch = dev_data->ppi_ch;
uint32_t gpiote_ch = dev_data->gpiote_ch;

if (dev_data->anomaly_58_workaround_active) {
nrf_ppi_channel_disable(NRF_PPI, ppi_ch);
nrf_gpiote_task_disable(gpiote.p_reg, gpiote_ch);

dev_data->anomaly_58_workaround_active = false;
}
}

static int anomaly_58_workaround_init(const struct device *dev)
{
struct spi_nrfx_data *dev_data = dev->data;
const struct spi_nrfx_config *dev_config = dev->config;
nrfx_err_t err_code;

dev_data->anomaly_58_workaround_active = false;

if (dev_config->anomaly_58_workaround) {
err_code = nrfx_ppi_channel_alloc(&dev_data->ppi_ch);
if (err_code != NRFX_SUCCESS) {
LOG_ERR("Failed to allocate PPI channel");
return -ENODEV;
}

err_code = nrfx_gpiote_channel_alloc(&gpiote, &dev_data->gpiote_ch);
if (err_code != NRFX_SUCCESS) {
LOG_ERR("Failed to allocate GPIOTE channel");
return -ENODEV;
}
LOG_DBG("PAN 58 workaround enabled for %s: ppi %u, gpiote %u",
dev->name, dev_data->ppi_ch, dev_data->gpiote_ch);
}

return 0;
}
#endif

static void finish_transaction(const struct device *dev, int error)
{
struct spi_nrfx_data *dev_data = dev->data;
Expand Down Expand Up @@ -544,26 +444,9 @@ static void transfer_next_chunk(const struct device *dev)
goto in_alloc_failed;
}

#ifdef CONFIG_SOC_NRF52832_ALLOW_SPIM_DESPITE_PAN_58
if (xfer.rx_length == 1 && xfer.tx_length <= 1) {
if (dev_config->anomaly_58_workaround) {
anomaly_58_workaround_setup(dev);
} else {
LOG_WRN("Transaction aborted since it would trigger "
"nRF52832 PAN 58");
error = -EIO;
}
}
#endif
if (error == 0) {
result = nrfx_spim_xfer(&dev_config->spim, &xfer, 0);
if (result == NRFX_SUCCESS) {
return;
}
error = -EIO;
#ifdef CONFIG_SOC_NRF52832_ALLOW_SPIM_DESPITE_PAN_58
anomaly_58_workaround_clear(dev_data);
#endif
result = nrfx_spim_xfer(&dev_config->spim, &xfer, 0);
if (result == NRFX_SUCCESS) {
return;
}

/* On nrfx_spim_xfer() error */
Expand Down Expand Up @@ -592,10 +475,6 @@ static void event_handler(const nrfx_spim_evt_t *p_event, void *p_context)
return;
}

#ifdef CONFIG_SOC_NRF52832_ALLOW_SPIM_DESPITE_PAN_58
anomaly_58_workaround_clear(dev_data);
#endif

if (spi_context_tx_buf_on(&dev_data->ctx)) {
dmm_buffer_out_release(dev_config->mem_reg,
(void **)p_event->xfer_desc.p_tx_buffer);
Expand Down Expand Up @@ -693,9 +572,6 @@ static int transceive(const struct device *dev,
#else
dev_data->ctx.ready = 0;
#endif /* CONFIG_MULTITHREADING */
#ifdef CONFIG_SOC_NRF52832_ALLOW_SPIM_DESPITE_PAN_58
anomaly_58_workaround_clear(dev_data);
#endif
} else if (error) {
finalize_spi_transaction(dev, true);
}
Expand Down Expand Up @@ -867,12 +743,6 @@ static int spi_nrfx_init(const struct device *dev)

spi_context_unlock_unconditionally(&dev_data->ctx);

#ifdef CONFIG_SOC_NRF52832_ALLOW_SPIM_DESPITE_PAN_58
err = anomaly_58_workaround_init(dev);
if (err < 0) {
return err;
}
#endif
return pm_device_driver_init(dev, spim_nrfx_pm_action);
}

Expand Down Expand Up @@ -957,10 +827,6 @@ static int spi_nrfx_deinit(const struct device *dev)
.irq_connect = irq_connect##idx, \
.pcfg = PINCTRL_DT_DEV_CONFIG_GET(SPIM(idx)), \
.max_chunk_len = BIT_MASK(SPIM_PROP(idx, easydma_maxcnt_bits)),\
COND_CODE_1(CONFIG_SOC_NRF52832_ALLOW_SPIM_DESPITE_PAN_58, \
(.anomaly_58_workaround = \
SPIM_PROP(idx, anomaly_58_workaround),), \
()) \
.wake_pin = NRF_DT_GPIOS_TO_PSEL_OR(SPIM(idx), wake_gpios, \
WAKE_PIN_NOT_USED), \
.wake_gpiote = WAKE_GPIOTE_INSTANCE(SPIM(idx)), \
Expand Down
7 changes: 0 additions & 7 deletions dts/bindings/spi/nordic,nrf-spim.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,6 @@ compatible: "nordic,nrf-spim"
include: ["nordic,nrf-spi-common.yaml", "memory-region.yaml"]

properties:
anomaly-58-workaround:
type: boolean
description: |
Enables the workaround for the nRF52832 SoC SPIM PAN 58 anomaly.
Must be used in conjunction with
CONFIG_SOC_NRF52832_ALLOW_SPIM_DESPITE_PAN_58=y
rx-delay-supported:
type: boolean
description: |
Expand Down
14 changes: 7 additions & 7 deletions modules/hal_nordic/nrfx/nrfx_kconfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -498,12 +498,15 @@
#ifdef CONFIG_NRFX_SPIM3
#define NRFX_SPIM3_ENABLED 1
#ifdef CONFIG_NRF52_ANOMALY_198_WORKAROUND
#define NRFX_SPIM3_NRF52840_ANOMALY_198_WORKAROUND_ENABLED 1
#define NRF52_ERRATA_198_ENABLE_WORKAROUND 1
#endif
#endif
#ifdef CONFIG_NRFX_SPIM4
#define NRFX_SPIM4_ENABLED 1
#endif
#ifdef CONFIG_NRF52_ANOMALY_58_WORKAROUND
#define NRF52_ERRATA_58_ENABLE_WORKAROUND 1
#endif

#define NRFX_SPIM_DT_HAS_RX_DELAY(node) DT_PROP(node, rx_delay_supported) +

Expand Down Expand Up @@ -815,10 +818,10 @@
#define NRFX_TWIM137_ENABLED 1
#endif
#ifdef CONFIG_NRF52_ANOMALY_219_WORKAROUND
#define NRFX_TWIM_NRF52_ANOMALY_219_WORKAROUND_ENABLED 1
#define NRF52_ERRATA_219_ENABLE_WORKAROUND 1
#endif
#ifdef CONFIG_SOC_NRF53_ANOMALY_47_WORKAROUND
#define NRFX_TWIM_NRF53_ANOMALY_47_WORKAROUND_ENABLED 1
#define NRF53_ERRATA_47_ENABLE_WORKAROUND 1
#endif

#ifdef CONFIG_NRFX_TWIS
Expand Down Expand Up @@ -1016,10 +1019,7 @@
#endif

#ifdef CONFIG_NRF52_ANOMALY_109_WORKAROUND
#define NRFX_SPIM_NRF52_ANOMALY_109_WORKAROUND_ENABLED 1
#define NRFX_SPIS_NRF52_ANOMALY_109_WORKAROUND_ENABLED 1
#define NRFX_TWIM_NRF52_ANOMALY_109_WORKAROUND_ENABLED 1
#define NRFX_PWM_NRF52_ANOMALY_109_WORKAROUND_ENABLED 1
#define NRF52_ERRATA_109_ENABLE_WORKAROUND 1
#define NRFX_PWM_NRF52_ANOMALY_109_EGU_INSTANCE \
CONFIG_NRF52_ANOMALY_109_WORKAROUND_EGU_INSTANCE
#endif
Expand Down
3 changes: 0 additions & 3 deletions samples/drivers/led/led_strip/boards/nrf52dk_nrf52832.conf

This file was deleted.

4 changes: 0 additions & 4 deletions soc/nordic/nrf52/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,6 @@
zephyr_library_sources(soc.c)
zephyr_include_directories(.)

if(CONFIG_SOC_NRF52832_ALLOW_SPIM_DESPITE_PAN_58 AND CONFIG_SPI_NRFX_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()

if(CONFIG_SOC_NRF52832)
if(NOT CONFIG_NRF52_ANOMALY_109_WORKAROUND)
if (CONFIG_NRFX_SPIS OR CONFIG_NRFX_SPIM OR CONFIG_NRFX_TWIM OR CONFIG_NRFX_PWM)
Expand Down
8 changes: 8 additions & 0 deletions soc/nordic/nrf52/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,14 @@ config NRF52_ANOMALY_132_DELAY_US
Additional drivers initialization increases initialization time and delay
may be shortened. Workaround is disabled by setting delay to 0.

config NRF52_ANOMALY_58_WORKAROUND
bool "Anomaly 58 workaround"
default y
depends on SOC_NRF52832
depends on NRFX_SPIM
help
This anomaly causes SPIM to clock out 2 bytes when 1 byte transfer was requested.

config NRF52_ANOMALY_198_WORKAROUND
bool "Anomaly 198 workaround"
default y
Expand Down
Loading