Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

nRF52: Properly configure nRF SDK for nRF52-series targets #12160

Merged
merged 5 commits into from
Jan 15, 2020

Conversation

AGlass0fMilk
Copy link
Member

@AGlass0fMilk AGlass0fMilk commented Dec 20, 2019

Summary of changes

Properly configure Nordic platform resource sharing (PRS) API so it actually delegates the shared interrupt slot for I2C/SPI to the appropriate peripheral.

Before this, the PRS system is enabled but none of the "boxes" are. This caused only the SPI interrupt handler to be properly installed in the NVIC table.

Also updated serial API to be fully migrated to using the UARTE peripheral driver (as opposed to the deprecated UART driver). Disabled the UART and TWIM drivers as these are not used by either serial_api.c nor i2c_api.c and were causing build issues.

Fixes #12159

Impact of changes

Migration actions required

Documentation


Pull request type

[X] Patch update (Bug fix / Target update / Docs update / Test update / Refactor)
[] Feature update (New feature / Functionality change / New API)
[] Major update (Breaking change E.g. Return code change / API behaviour change)

Test results

[] No Tests required for this change (E.g docs only update)
[X] Covered by existing mbed-os tests (Greentea or Unittest)
[] Tests / results supplied as part of this PR

Reviewers

@desmond-blue


@ciarmcom
Copy link
Member

@AGlass0fMilk, thank you for your changes.
@desmond-blue @ARMmbed/mbed-os-maintainers please review.

@AGlass0fMilk
Copy link
Member Author

@maclobdell

Copy link
Contributor

@desmond-blue desmond-blue left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me.

@bulislaw
Copy link
Member

CI started

@mbed-ci
Copy link

mbed-ci commented Dec 23, 2019

Test run: FAILED

Summary: 1 of 4 test jobs failed
Build number : 1
Build artifacts

Failed test jobs:

  • jenkins-ci/mbed-os-ci_build-ARM

@adbridge
Copy link
Contributor

Looks like it could be an ARM licence issue , restarted

@mbed-ci
Copy link

mbed-ci commented Dec 23, 2019

Test run: FAILED

Summary: 1 of 4 test jobs failed
Build number : 2
Build artifacts

Failed test jobs:

  • jenkins-ci/mbed-os-ci_build-ARM

@adbridge
Copy link
Contributor

Looks like there is a genuine ARMC error as the following targets all failed:

    Build ARM / MTB_LAIRD_BL652 / Build MTB_LAIRD_BL652 / MTB_LAIRD_BL652-ARM.build.build-greentea_tests
    Build ARM / SDT52832B / Build SDT52832B / SDT52832B-ARM.build.build-greentea_tests
    Build ARM / MTB_MURATA_WSM_BL241 / Build MTB_MURATA_WSM_BL241 / MTB_MURATA_WSM_BL241-ARM.build.build-greentea_tests
    Build ARM / NRF52_DK / Build NRF52_DK / NRF52_DK-ARM.build.build-greentea_tests
    Build ARM / UBLOX_EVK_NINA_B1 / Build UBLOX_EVK_NINA_B1 / UBLOX_EVK_NINA_B1-ARM.build.build-greentea_tests
    Build ARM / MTB_ACONNO_ACN52832 / Build MTB_ACONNO_ACN52832 / MTB_ACONNO_ACN52832-ARM.build.build-greentea_tests
    Build ARM / MTB_UBLOX_NINA_B1 / Build MTB_UBLOX_NINA_B1 / MTB_UBLOX_NINA_B1-ARM.build.build-greentea_tests
    Build ARM / MTB_LAIRD_BL654 / Build MTB_LAIRD_BL654 / MTB_LAIRD_BL654-ARM.build.build-greentea_tests
    Build ARM / EP_AGORA / Build EP_AGORA / EP_AGORA-ARM.build.build-greentea_tests
    Build ARM / NRF52840_DK / Build NRF52840_DK / NRF52840_DK-ARM.build.build-greentea_tests
    Build ARM / SDT52832B / Build SDT52832B / SDT52832B-ARM.build.build-examples
    Build ARM / UBLOX_EVK_NINA_B1 / Build UBLOX_EVK_NINA_B1 / UBLOX_EVK_NINA_B1-ARM.build.build-examples
    Build ARM / MTB_MURATA_WSM_BL241 / Build MTB_MURATA_WSM_BL241 / MTB_MURATA_WSM_BL241-ARM.build.build-examples
    Build ARM / MTB_ACONNO_ACN52832 / Build MTB_ACONNO_ACN52832 / MTB_ACONNO_ACN52832-ARM.build.build-examples
    Build ARM / MTB_LAIRD_BL652 / Build MTB_LAIRD_BL652 / MTB_LAIRD_BL652-ARM.build.build-examples
    Build ARM / MTB_UBLOX_NINA_B1 / Build MTB_UBLOX_NINA_B1 / MTB_UBLOX_NINA_B1-ARM.build.build-examples
    Build ARM / NRF52840_DK / Build NRF52840_DK / NRF52840_DK-ARM.build.build-examples
    Build ARM / MTB_LAIRD_BL654 / Build MTB_LAIRD_BL654 / MTB_LAIRD_BL654-ARM.build.build-examples
    Build ARM / EP_AGORA / Build EP_AGORA / EP_AGORA-ARM.build.build-examples
    Build ARM / NRF52_DK / Build NRF52_DK / NRF52_DK-ARM.build.build-examples

But I cannot see why they failed! @VeliMattiLahtela any idea why these failures are not giving any details ?

@0Grit
Copy link

0Grit commented Dec 27, 2019

@marcuschangarm in case this sounds familiar

@AGlass0fMilk
Copy link
Member Author

@adbridge Any update on the source of the build failures? It's probably related to the macros I changed in this PR...

@0xc0170
Copy link
Contributor

0xc0170 commented Jan 3, 2020

@AGlass0fMilk You can review build artifacts, there are multiple defined symbols errors.

[Error] @0,0: L6218E: Undefined symbol nrfx_twim_1_irq_handler (referred from BUILD/EP_AGORA/ARM/mbed-os/targets/TARGET_NORDIC/TARGET_NRF5x/TARGET_SDK_15_0/modules/nrfx/drivers/src/nrfx_twim.o).

Same file as changed here.

@AGlass0fMilk
Copy link
Member Author

@0xc0170 We actually don't use nrfx_twim.c as far as I know. The I2C driver used for master mode is nrfx_twi.c. I'll look into this more.

@AGlass0fMilk
Copy link
Member Author

AGlass0fMilk commented Jan 9, 2020

Alright, I think I found the issue. For some reason only ARMC6 was failing even though the Nordic SDK was still pretty misconfigured.

Serial API/UART Fix

It seems at some point the serial_api.c implementation migrated from using the (deprecated) UART peripheral and started using the UARTE (low-power UART) peripheral present on nRF52-series devices.

Whoever did that migration never changed all the types to use the corresponding types from nrf_uarte.h (they are identical to nrf_uart.h, but it's the principle!). Thus they also left NRFX_UART and NRF_UART, etc, enabled (which the serial_api.c implementation no longer uses in lieu of NRFX_UARTE).

It seems the PRS system doesn't allow the use of the UART and UARTE peripherals at the same time (they are functionally the same and share the same memory-mapped location in some cases) so that was causing the undefined symbol the linker was looking for. This has been fixed by completely migrating from UART to UARTE and disabling the deprecated UART peripheral driver.

I2C Fix

Similar to the UART sitatuion, there are several peripherals that support I2C master mode. Namely, TWI and TWIM. In Mbed's case, we're using TWI (the older, deprecated peripheral supporting I2C master). The developer implementing the i2c_api.c support for nRF52 must have misunderstood the distinction and kept both TWI and TWIM peripherals enabled -- causing conflicts.

In the same way, the PRS system does not allow TWI and TWIM to be used at the same time.

This issue was fixed by simply disabling the TWIM peripheral driver in the SDK. The build runs fine, still need to test on a real target but the CI should do that...

Since the TWI peripheral used by Mbed-OS's nRF52 I2C master implementation is "deprecated" it should eventually be migrated to use the TWIM. The I2CSlave implementation is already based on the (newer) TWIS peripheral so no migration effort is needed there.

I don't think there's much priority to migrating until Mbed starts supporting the newer Nordic chips (91-series, 53-series, etc)

@0xc0170

@AGlass0fMilk AGlass0fMilk changed the title [nRF52] Properly configure PRS API [nRF52] Properly configure nRF SDK for nRF52-series targets Jan 9, 2020
…nused TWIM peripheral (deprecated TWI peripheral is currently used for I2C master mode operation).
@AGlass0fMilk
Copy link
Member Author

Momentarily screwed up the history with the rebase but I think I fixed it 😅

@AGlass0fMilk
Copy link
Member Author

The striked out assumptions above are wrong upon closer examination:

What's really happening is when the PRS system is disabled, the IRQs for each peripheral driver actually conflict since they all point to the same function definition (see excerpt below in the case of nRF52840):

// SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0_IRQn
#if NRFX_CHECK(NRFX_PRS_ENABLED) && NRFX_CHECK(NRFX_PRS_BOX_0_ENABLED)
#define nrfx_prs_box_0_irq_handler SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0_IRQHandler
#else
#define nrfx_spim_0_irq_handler SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0_IRQHandler
#define nrfx_spis_0_irq_handler SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0_IRQHandler
#define nrfx_twim_0_irq_handler SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0_IRQHandler
#define nrfx_twis_0_irq_handler SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0_IRQHandler
#define nrfx_spi_0_irq_handler SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0_IRQHandler
#define nrfx_twi_0_irq_handler SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0_IRQHandler
#endif
// SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1_IRQn
#if NRFX_CHECK(NRFX_PRS_ENABLED) && NRFX_CHECK(NRFX_PRS_BOX_1_ENABLED)
#define nrfx_prs_box_1_irq_handler SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1_IRQHandler
#else
#define nrfx_spim_1_irq_handler SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1_IRQHandler
#define nrfx_spis_1_irq_handler SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1_IRQHandler
#define nrfx_twim_1_irq_handler SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1_IRQHandler
#define nrfx_twis_1_irq_handler SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1_IRQHandler
#define nrfx_spi_1_irq_handler SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1_IRQHandler
#define nrfx_twi_1_irq_handler SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1_IRQHandler
#endif

With the PRS system enabled properly, the interrupts handlers then become locally-declared functions that are then installed by the PRS when nrfx_prs_acquire is called. This avoids an IRQ symbol conflict if multiple peripherals are used that share the same underlying memory region.

Once I enabled the PRS "boxes" then all the IRQ handlers for each driver became locally-declared functions.

The failure we were seeing here was that the previous developer had preprocessored-out (using #if 0) the local declarations of each handler so the symbols no longer existed:

#if 0
#if NRFX_CHECK(NRFX_TWI0_ENABLED)
void nrfx_twi_0_irq_handler(void)
{
twi_irq_handler(NRF_TWI0, &m_cb[NRFX_TWI0_INST_IDX]);
}
#endif
#endif
#if 0
#if NRFX_CHECK(NRFX_TWI1_ENABLED)
void nrfx_twi_1_irq_handler(void)
{
twi_irq_handler(NRF_TWI1, &m_cb[NRFX_TWI1_INST_IDX]);
}
#endif
#endif

The reason it would build before was because none of the boxes were enabled so the symbols were all redirected to the global interrupt symbol for each "box" (eg: SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0_IRQHandler).

I am surprised we haven't seen any failures/issues related to this. It would only affect users trying to use asynchronous I2C and asynchronous SPI on the same instance I think...

Regardless, I think the PR fixes all these issues and resources should be shared appropriately now.

@0xc0170
Copy link
Contributor

0xc0170 commented Jan 10, 2020

CI started

@mbed-ci
Copy link

mbed-ci commented Jan 10, 2020

Test run: FAILED

Summary: 1 of 4 test jobs failed
Build number : 3
Build artifacts

Failed test jobs:

  • jenkins-ci/mbed-os-ci_build-IAR

@0xc0170
Copy link
Contributor

0xc0170 commented Jan 10, 2020

[Error] pal_uart.c@55,0: [Pe094]: the size of an array must be greater than zero

IAR failed , please review

@AGlass0fMilk
Copy link
Member Author

Fixed outdated references to UARTx_ENABLED preprocessor macros in lieu of new NRFX_UARTEx_ENABLED macros.

@0xc0170

@0xc0170 0xc0170 changed the title [nRF52] Properly configure nRF SDK for nRF52-series targets nRF52: Properly configure nRF SDK for nRF52-series targets Jan 13, 2020
@mbed-ci
Copy link

mbed-ci commented Jan 13, 2020

Test run: SUCCESS

Summary: 11 of 11 test jobs passed
Build number : 4
Build artifacts

@0xc0170 0xc0170 merged commit cbca99d into ARMmbed:master Jan 15, 2020
@AGlass0fMilk AGlass0fMilk deleted the fix-prs-config branch January 16, 2020 20:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
release-version: 6.0.0-alpha-2 Second pre-release version of 6.0.0
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Nordic] TWI/I2C interrupts never get installed
8 participants