Git Product home page Git Product logo

Comments (21)

Fabien-Chouteau avatar Fabien-Chouteau commented on July 22, 2024

Hi Rob,
The I2C protocol can be used in different ways. The Python version doesn't send stop/start tokens between address and data access, but that doesn't necessarily explain the problem.

What error do you see?

from ada_drivers_library.

rveenker avatar rveenker commented on July 22, 2024

Hello Fabien,
What I see is that the values from the mma8653 do not change at all and sometimes there are no values at all.
Only after running another program that also uses the mma8653, I get results that make sense.
So my guess was that the problem is caused by incorrect or incomplete initialization.
For testing, I modified the accelerometer so that it sends the exact same register values as the python program, but this did not solve the issue.
Do you have suggestions on how to proceed? Thanks!

from ada_drivers_library.

Fabien-Chouteau avatar Fabien-Chouteau commented on July 22, 2024

For testing, I modified the accelerometer so that it sends the exact same register values as the python program, but this did not solve the issue.

That's what I would have recommended. So if it doesn't work I don't know what to say...

from ada_drivers_library.

simonjwright avatar simonjwright commented on July 22, 2024

I couldn't get the accelerometer example to work (it was constantly returning the same values). I tried the mu MicroPython development environment as recommended here, and that didn't work either. So I tried restoring the standard firmware instead of the Segger JLink version - success!

Need to check out pyOCD.

from ada_drivers_library.

rveenker avatar rveenker commented on July 22, 2024

Unfortunately still not able to get the accelerometer example running on my MicroBit V1.3b. The firmware versions I used are 0241, 0249 and 0253. In all cases I get the arrow, but the values remain the same.

Now that I also have a MicroBit v1.5 (firmware 0253), I was curious if the problem persisted.
I rewrote the accelerometer example to use the LSM303AGR instead of the MMA8653. The example works, but with exactly the same precondition.
In order to work, the accelerometer must be used first (initialized) by another (python) program.

@simon, Did the example also work after power down/up? If so, Where can I find the firmware (.hex) files you used?
Thanks in advance!

from ada_drivers_library.

simonjwright avatar simonjwright commented on July 22, 2024

I'm at this moment using 0243.

I'm sorry to have misled you before: what I think I meant (it was a bit of a drive-by) was that mu wouldn't load with the Segger firmware, but did with the standard version; and after that the Ada code worked. So now I'm in exactly the same position as you.

I see that on my other Mac I made some changes to the MMA8653 setup; I'll need some time (and opportunity) to work out where I'd got to.

from ada_drivers_library.

simonjwright avatar simonjwright commented on July 22, 2024

I don’t think the problem is with the accelerometer; it’s with TWI (Nordic’s I2C implementation).
I looked at the TWI peripheral data while the accelerometer was working (after Python initialisation) and while it wasn’t, and couldn’t see any obviously-significant difference.
I tried running under Cortex GNAT RTS, which involved some changes because it’s a Ravenscar RTS; with this, both with and without Python initialisation, reading the chip’s whoami register returns 0 (there’s no visible display, because this is happening during elaboration, so tasking isn’t running yet).
I can only think there’s some undocumented board initialisation which my microbit (1.3B - at any rate, the FCC ID is 2AKFPMB013B) requires, which is done somewhere in mu. I tried looking at microbit-dal, not very helpful (it seems to be incomplete, for a start).
I hate to abandon something like this!

from ada_drivers_library.

rveenker avatar rveenker commented on July 22, 2024

Since the problem occurs with both V1.3B and V1.5 boards and with the MMA8653 an LSM303AGR, I don't think it is hardware related. It must be some sort of initialization issue indeed.
@simon, Thanks for investigating!

from ada_drivers_library.

Fabien-Chouteau avatar Fabien-Chouteau commented on July 22, 2024

Did you both tried with this change applied? #402

from ada_drivers_library.

simonjwright avatar simonjwright commented on July 22, 2024

@Fabien-Chouteau - yes. I did wonder whether there was an issue with HFCLOCK, but so far as I can see there’s no difference between working & non-working setups (I’m a little unsure about this, because to run mu I need a standard firmware, which means I have to use pyocd, which can’t access peripheral memory ...)

from ada_drivers_library.

simonjwright avatar simonjwright commented on July 22, 2024

I found that the board could be put into the working state by running BBC-MicroBit-First-Experience-1460979530935.hex (which means I can carry on with the JLink firmware, and get a better debug experience than I’ve got with pyocd - which also doesn’t run on my M1 mac).

It seemed to me that the retained settings in the nRF51 would most likely be in TWI, GPIO, or GPIOTE. Unfortunately, there was no difference between these when running from power-on or after the First Experience firmware.

I also tried running a VL53L1X - again, didn’t work. I should try running after the First Experience ...

from ada_drivers_library.

JeremyGrosser avatar JeremyGrosser commented on July 22, 2024

I tried this on a v1.3b board with 0253 firmware. The accelerometer works for me.

Here's the code I used: https://github.com/JeremyGrosser/microbit_accel

from ada_drivers_library.

JeremyGrosser avatar JeremyGrosser commented on July 22, 2024

Hmm, I commented too soon... After a power cycle, I see the same behavior @simonjwright reported, which is that it always returns the same obviously incorrect values.

from ada_drivers_library.

JeremyGrosser avatar JeremyGrosser commented on July 22, 2024

I've been looking into this for a few hours and I'm fairly convinced that @Fabien-Chouteau was right in his first comment... The Python driver correctly sends a Repeated Start between the address and data sections of a transaction, whereas nRF.TWI is sending Stop then Start.

The MMA8653 datasheet pretty clearly shows that repeated starts are required on this device. We'll need to modify the TWI driver to support that.

I'm not sure why it works when the Ada code is loaded after the Python code. The state machine is a bit complicated, but my best guess is that the Python code is leaving the TWI peripheral in the middle of a transaction, after sending STARTTX but before calling STOP. When the Ada driver then calls STARTTX a second time, the hardware issues a repeated start.

Likely unrelated, but worth noting: The I2C clock is running a bit fast... Measuring 410-421 KHz with my logic analyzer. The MMA8653 is only specified up to 400 KHz, though it appears to be responding at this slightly out of spec speed. Still, we should fix the clock.

I've started working on a rewrite of the TWI driver, similar to what I did with RP.I2C. It's going to take some time.

from ada_drivers_library.

simonjwright avatar simonjwright commented on July 22, 2024

I think both of the changes here are necessary, the first to supply the missing initialization, the second to avoid the stop/start issue.

diff --git a/arch/ARM/Nordic/drivers/nrf_common/nrf-twi.adb b/arch/ARM/Nordic/drivers/nrf_common/nrf-twi.adb
index d3423ec6..a09a65f6 100644
--- a/arch/ARM/Nordic/drivers/nrf_common/nrf-twi.adb
+++ b/arch/ARM/Nordic/drivers/nrf_common/nrf-twi.adb
@@ -134,6 +134,9 @@ package body nRF.TWI is
       --  Set Address
       This.Periph.ADDRESS.ADDRESS := UInt7 (Addr / 2);
 
+      This.Periph.SHORTS.BB_SUSPEND := Disabled;
+      This.Periph.SHORTS.BB_STOP := Disabled;
+
       --  Prepare first byte
       This.Periph.TXD.TXD := Data (Data'First);
 
@@ -266,34 +269,29 @@ package body nRF.TWI is
    is
    begin
 
-      This.Do_Stop_Sequence := False;
+      This.Do_Stop_Sequence := True;
 
       case Mem_Addr_Size is
          when Memory_Size_8b =>
             This.Master_Transmit (Addr    => Addr,
-                                  Data    => (0 => UInt8 (Mem_Addr)),
+                                  Data    =>
+                                    (0 => UInt8 (Mem_Addr)) & Data,
                                   Status  => Status,
                                   Timeout => Timeout);
          when Memory_Size_16b =>
             This.Master_Transmit (Addr    => Addr,
-                                  Data    => (UInt8 (Shift_Right (Mem_Addr, 8)),
-                                              UInt8 (Mem_Addr and 16#FF#)),
+                                  Data    =>
+                                    (UInt8 (Shift_Right (Mem_Addr, 8)),
+                                     UInt8 (Mem_Addr and 16#FF#)) & Data,
                                   Status  => Status,
                                   Timeout => Timeout);
       end case;
 
 
-      This.Do_Stop_Sequence := True;
-
       if Status /= Ok then
          This.Stop_Sequence;
          return;
       end if;
-
-      This.Master_Transmit (Addr    => Addr,
-                            Data    => Data,
-                            Status  => Status,
-                            Timeout => Timeout);
    end Mem_Write;
 
    --------------

from ada_drivers_library.

JeremyGrosser avatar JeremyGrosser commented on July 22, 2024

With that patch, the accelerometer appears to be initialized correctly after power cycle and is using repeated starts in I2C transactions. Seems like a good fix to me!

from ada_drivers_library.

simonjwright avatar simonjwright commented on July 22, 2024

I also tried against an external VL53L1X; didn’t work before the change, OK afterward.

Interestingly, the MMA8653 datasheet says there shouldn’t be a stop/start between the transmit & receive parts of a read request, yet inserting them seems to be fine. Also, the VL53L1X datasheet has subtly different expectations!

from ada_drivers_library.

JeremyGrosser avatar JeremyGrosser commented on July 22, 2024

There are some older I2C devices that won't work with repeated starts but generally anything with silicon designed in the last 15-20 years should be okay. It would be nice to have a switch to turn off repeated start, but it's probably unnecessary these days.

from ada_drivers_library.

rveenker avatar rveenker commented on July 22, 2024

Just tried the proposed fix on my two Micro:bit boards (V1.3B using the mma8653 and V1.5 which uses the LSM303AGR), and can say that the fix works on both devices.
Thanks for fixing this issue!

from ada_drivers_library.

rveenker avatar rveenker commented on July 22, 2024

I noticed that on the V1.3B board, the accelerometer demo also works after being disconnected, however on the V1.5 board the demo starts after loading, but not from a cold start.
There may still be an issue with the LSM303AGR.

from ada_drivers_library.

rveenker avatar rveenker commented on July 22, 2024

Connecting power to the V1.5 board apparently behaves differently, because on this board you also need to press the reset button :-)
So I guess there is no issue with the LSM303AGR.

from ada_drivers_library.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.