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

Nordic RF52 does not correctly support simultaneous use of I2C and SPI #4357

Closed
NeilMacMullen opened this issue May 21, 2017 · 23 comments
Closed

Comments

@NeilMacMullen
Copy link
Contributor

NeilMacMullen commented May 21, 2017

Mbed OS 5
Target UBLOX_EVK_NINA_B1
Toolchain GCC_ARM

The Nordic RF52 SoC uses digital 'TWI' control blocks to control both I2C and SPI. When declaring an I2C object, the Nordic platform code in targets/TARGET_NORDIC/TARGET_NRF5/i2c_api.c uses the method "i2c_init" to allocate the first available TWI by examining previously-allocated I2C instances. Similar code is used in the SPI drivers (spi_api.c) where previously-allocated SPI instances are checked.

This approach fails when allocating a mixture of I2C and SPI instances since both _init methods then consider TWI0 to be available and allocate it to both the I2C and SPI interfaces. This leads to unpredictable results when the interfaces are used.

If you only have a single I2C and SPI instance, it's possible to work around this by forcing one of the allocators to allocate TWI1 (example code below) but the correct fix would be to implement a central allocator which would be used for both types of interface.

diff --git a/targets/TARGET_NORDIC/TARGET_NRF5/i2c_api.c b/targets/TARGET_NORDIC/TARGET_NRF5/i2c_api.c
index 66063b4..ca551d4 100644
--- a/targets/TARGET_NORDIC/TARGET_NRF5/i2c_api.c
+++ b/targets/TARGET_NORDIC/TARGET_NRF5/i2c_api.c
@@ -283,6 +283,7 @@ static void twi_clear_bus(twi_info_t *twi_info)
     }
}
+#define I2C_TWI 1
void i2c_init(i2c_t *obj, PinName sda, PinName scl)
{
     int i;
@@ -290,7 +291,7 @@ void i2c_init(i2c_t *obj, PinName sda, PinName scl)
         if (m_twi_info[i].initialized &&
             m_twi_info[i].pselsda == (uint32_t)sda &&
             m_twi_info[i].pselscl == (uint32_t)scl) {
-            TWI_IDX(obj) = i;
+            TWI_IDX(obj) = I2C_TWI;
             TWI_INFO(obj)->frequency = NRF_TWI_FREQ_100K;
             i2c_reset(obj);
             return;
@@ -299,7 +300,7 @@ void i2c_init(i2c_t *obj, PinName sda, PinName scl)
 
     for (i = 0; i < TWI_COUNT; ++i) {
         if (!m_twi_info[i].initialized) {
-            TWI_IDX(obj) = i;
+            TWI_IDX(obj) = I2C_TWI;
 
             twi_info_t *twi_info = TWI_INFO(obj);
             twi_info->initialized = true;
 

Copying @MarceloSalazar by request

@0xc0170
Copy link
Contributor

0xc0170 commented May 22, 2017

cc @nvlsianpu @pan-

@nvlsianpu
Copy link
Contributor

Thank you for describing this bug.

@shayo
Copy link

shayo commented Jun 20, 2017

@nvlsianpu, we are experiencing the same bug here as well.
Our board has both I2C and SPI.
When we define both SPI and I2C, none of them work.
When I remove the declaration of SPI, I2C works.

Is there a patch to solve this issue? I tried taking the latest code but the problem is still there.
This is a major blocker for us right now.

@shayo
Copy link

shayo commented Jun 20, 2017

@NeilMacMullen , I also tried your solution (modifying the i2c_init), but it didn't work for me. Is there something else I can try? Which version did you base your patch on?

@nvlsianpu
Copy link
Contributor

did you test the path #4491?

@shayo
Copy link

shayo commented Jun 20, 2017

I've tried c416fdf, after you added the central resource manager. It still doesn't work (both I2C and SPI).

@shayo
Copy link

shayo commented Jun 20, 2017

It seems like the system hangs with your branch when I call "wait".
This happens also when I use the main branch.
Are there also changes to us_ticker_read that I should take from somewhere?
This might also explain why the SPI code initialization hang.

@NeilMacMullen
Copy link
Contributor Author

@nvlsianpu - apologies, I didn't get any notification of #4491 so have only just seen this change. @shayo - I will try this here and let you know whether it works for me.

@NeilMacMullen
Copy link
Contributor Author

@nvlsianpu @shayo I agree that this seems at first sight to be broken. I did... "git pull origin pull/4491/head" in a new project then verified that the i2c_api file does include the latest changes then copied my application source to the new project and built it. In my case, the symptoms are that "i2c->write(address, NULL, 0);" returns 0 for any address, indicating that the entire bus is populated with devices. The same code without these changes (and with my original workaround) correctly identifies the few I2C devices I have on the bus.

@shayo
Copy link

shayo commented Jun 20, 2017

@NeilMacMullen , which branch/version did you apply your changes to?

@NeilMacMullen
Copy link
Contributor Author

@shayo - I just used 'mbed update to get a recent version. According to git log, last couple of commits were...
commit ed4febe
commit 9ce6141

@shayo
Copy link

shayo commented Jun 23, 2017

@nvlsianpu, any news on this?

@NeilMacMullen
Copy link
Contributor Author

@shayo -see the comment on the PR - looks like there will be another attempt at this.

@nvlsianpu
Copy link
Contributor

Status in progress: #4491 (comment)

@nvlsianpu
Copy link
Contributor

@NeilMacMullen Are you able to test whether #4634 fixes the issue?

nvlsianpu added a commit to nvlsianpu/mbed that referenced this issue Jun 27, 2017
Use serial-box of Nordic nRF5 SDK to share resource between
SPI and I2C.
SPI is allocated from highest hw instance number resource in order
to allocate as many I2C instances as possible.
@NeilMacMullen
Copy link
Contributor Author

@nvlsianpu - sorry for not getting back to you earlier. Unfortunately #4634 also appears to have problems. Although I can successfully now detect I2C devices on the bus and also use a serial flash on the SPI bus, the application appears to crash on a subsequent call to Thread::wait. This does not occur with my original changes on earlier mbed.

@NeilMacMullen
Copy link
Contributor Author

@nvlsianpu - actually the issue above may be a red herring. It looks like something else has changed between 4.5 and 5.5 to break my application.

@nvlsianpu
Copy link
Contributor

OS 5.5 upgrades to the latest CMSIS version, CMSIS5, including the CMSIS-RTOS2 kernel. So changes were big. Did you tried latest minor release 5.5.1?

@NeilMacMullen
Copy link
Contributor Author

@nvlsianpu I've raised this issue as #4686 - it appears to be a regression on the Serial driver.

0xc0170 added a commit that referenced this issue Jul 13, 2017
…ultaneously

 Fix the issue #4357: NRF52 doesn't support simultaneous use of I2C and SPI.
adbridge pushed a commit that referenced this issue Jul 14, 2017
Use serial-box of Nordic nRF5 SDK to share resource between
SPI and I2C.
SPI is allocated from highest hw instance number resource in order
to allocate as many I2C instances as possible.
@seppestas
Copy link
Contributor

What's the status of the issue? We are also experiencing weird problems with I2C interface that might be explained by this issue (branch based on mbed-os 5.4.7).

It looks like this issue was fixed in PR #4634, but this issue is still open. Is there a reason for this?

@NeilMacMullen
Copy link
Contributor Author

@seppestas Sorry not to reply earlier. From my testing the issue appears to be resolved on 5.6. Having said that, I am interested in the nature of the problems you are seeing. We still see a high level of I2C failures and SPI lockups even with this fix. I'm still trying to establish whether this is actually a hardware issue or further issues with software/digits.

@nvlsianpu
Copy link
Contributor

This is what I have on output form ci-test-shield test for concurrent I2C/SPI verification (see https://github.com/ARMmbed/ci-test-shield/blob/master/TESTS/concurrent/Comms/Comms.cpp):
Test was compiled against NRF52_DK@ARM_GCC

image

I ran it by hand for mitigating any IF firmware problems we have.
Can we close this bug?

@0xc0170
Copy link
Contributor

0xc0170 commented Nov 17, 2017

Thanks @NeilMacMullen and @nvlsianpu for the updates

@0xc0170 0xc0170 closed this as completed Nov 17, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants