Updating from NCS2.6 to 2.8, the access to my QPSI Flash chip got broken (mx25r64, connected and configured using QPSI exactly as per the nrf5340DK board)
DTS entry:
&qspi { // external flash status = "okay"; pinctrl-0 = <&qspi_default>; pinctrl-1 = <&qspi_sleep>; pinctrl-names = "default", "sleep"; mx25r64: mx25r6435f@0 { compatible = "nordic,qspi-nor"; reg = <0>; /* MX25R64 supports only pp and pp4io */ writeoc = "pp4io"; /* MX25R64 supports all readoc options */ readoc = "read4io"; sck-frequency = <8000000>; jedec-id = [c2 28 17]; sfdp-bfp = [ e5 20 f1 ff ff ff ff 03 44 eb 08 6b 08 3b 04 bb ee ff ff ff ff ff 00 ff ff ff 00 ff 0c 20 0f 52 10 d8 00 ff 23 72 f5 00 82 ed 04 cc 44 83 68 44 30 b0 30 b0 f7 c4 d5 5c 00 be 29 ff f0 d0 ff ff ]; size = <67108864>; has-dpd; t-enter-dpd = <10000>; t-exit-dpd = <35000>; }; };
When accessing it, I now get these logs:
[00:00:15.432,556] <err> qspi_nor: nRF5340 anomaly 159 conditions detected
[00:00:15.440,032] <err> qspi_nor: Set the CPU clock to 64 MHz before starting QSPI operation
and then any flash access (eg to filesystem access using ELM) fails. On NCS2.6 this all worked fine.
This appears to be a 'fix' for anomly 159 (which I was not aware of experiencing!) which notes that if the HCLK_192M divider is not 0 _and_ the CPU clock is >64MHz then QSPI accesses can fail.
Digging into this, the log comes from zephyr/drivers/flasqh/nrf_qspi_nor.c (which uses modules/hal/nordic/nrfx/drivers/src/nrf_qpsi.c). The log is actually just when the code translates the underlying error of NRFX_ERROR_FORBIDDEN into a ECANCELED:
static int _prev_hclk_div=0; static inline void qspi_clock_div_change(void) { #ifdef CONFIG_SOC_SERIES_NRF53X /* Make sure the base clock divider is changed accordingly * before a QSPI transfer is performed. */ nrf_clock_hfclk192m_div_set(NRF_CLOCK, BASE_CLOCK_DIV); k_busy_wait(BASE_CLOCK_SWITCH_DELAY_US); #ifdef NRF53_ERRATA_159_ENABLE_WORKAROUND _prev_hclk_div = nrf_clock_hfclk_div_get(NRF_CLOCK); nrf_clock_hfclk_div_set(NRF_CLOCK, NRF_CLOCK_HFCLK_DIV_2); //nrfx_clock_divider_set(NRF_CLOCK_DOMAIN_HFCLK, NRF_CLOCK_HFCLK_DIV_1); #endif #endif } static inline void qspi_clock_div_restore(void) { #ifdef CONFIG_SOC_SERIES_NRF53X /* Restore the default base clock divider to reduce power * consumption when the QSPI peripheral is idle. */ nrf_clock_hfclk192m_div_set(NRF_CLOCK, NRF_CLOCK_HFCLK_DIV_4); #ifdef NRF53_ERRATA_159_ENABLE_WORKAROUND // set back to previous cpu clk speed nrf_clock_hfclk_div_set(NRF_CLOCK, _prev_hclk_div); #endif #endif }