sparkfun / OpenLog_Artemis

The OpenLog Artemis is an open source datalogger the comes preprogrammed to automatically log IMU, GPS, serial data, and various pressure, humidity, and distance sensors. All without writing a single line of code!
https://www.sparkfun.com/products/15846
Other
88 stars 47 forks source link

Getting 224 WhoAmI on IMU (Apollo 2.0.4) - CIPO Issue? #69

Closed u382514 closed 3 years ago

u382514 commented 3 years ago

Subject of the issue

I know it's a 2.0.4 issue again and we know 2.0.4 isn't mature yet, but hear me out! I'm attempting to get the basic 234 WhoAmI result from the ICM-20948 chip. I noticed on OLA on 1.2.1 it will read 224 if the CIPO is not enabled and will give the proper 234 result if the CIPO IS enabled. I'm assuming this is by design but have no idea why or how.

In 2.0.4, not matter how I configure the CIPO enable logic, I always get the 224 reading and cannot get past it. I'm posting the issue here as I'm sure you folks are much more aware of the inner workings of the 'why' on this board.

Does anyone have any ideas on where to go from here?

Your workbench

Steps to reproduce

The sketch below is a fully working sketch. You should be able to put it in a sketch file and easily compile it under 1.2.1. With the little work above for 2.0.4 you should be able to get it to compile there just as easy without any changes to the sketch code.

Note: The CIPO enable logic will look a bit different just because I took out the middleman due to differences in Apollo versions (namely, no padMode). Although I took a more direct route, it's essentially the same path leading to the am_hal_gpio_pinconfig functon.

// OLA PINS
const byte PIN_IMU_POWER = 27;
const byte PIN_IMU_CHIP_SELECT = 44;

///////////////////////////
// Added variables here to satisfy requirements needed to test on 1.2.1 an 2.0.4 

#include "SPI.h"
#include "am_hal_gpio.h"

//2.0 doesn't have the NULL config so we make it here to match 1.2
const am_hal_gpio_pincfg_t AP3_GPIO_PINCFG_NULL_1_2 = 
    {
        .uFuncSel = 0,       
        .ePowerSw = 0,       
        .ePullup = 0,        
        .eDriveStrength = 0,
        .eGPOutcfg = 0,     
        .eGPInput = 0,      
        .eIntDir = 0,        
        .eGPRdZero = 0,     
        .uIOMnum = 0, 
        .uNCE = 0,    
        .eCEpol = 0,  
        .uRsvd22 = 0
};

const SPISettings spisettings = SPISettings(4000000, MSBFIRST, 0);

void setup() {
  Serial.begin(115200);
  SPI.begin();

///////////////////////////
// The OLA enableCIPOPullup logic, but in a format that compiles on both 1.2.1 and 2.0.4 of Apollo. 
// This logic still gives 224 if disabled and 234 if enabled. 

  am_hal_gpio_pincfg_t cipoPinCfg = AP3_GPIO_PINCFG_NULL_1_2;
  cipoPinCfg.uFuncSel = 1; //AM_HAL_PIN_6_M0MISO
  cipoPinCfg.eDriveStrength = 3; //AM_HAL_GPIO_PIN_DRIVESTRENGTH_12MA
  cipoPinCfg.eGPOutcfg = 1; //AM_HAL_GPIO_PIN_OUTCFG_PUSHPULL
  cipoPinCfg.uIOMnum = 0; //AP3_SPI_IOM
  cipoPinCfg.ePullup = 2; //AM_HAL_GPIO_PIN_PULLUP_1_5K
  am_hal_gpio_pinconfig(6, cipoPinCfg); //MISO = 6 -- Simply comment out this line to get a 224 on 1.2.1

///////////////////////////
// OLA Logic to power down and power up IMU just in case

  pinMode(PIN_IMU_CHIP_SELECT, OUTPUT);
  digitalWrite(PIN_IMU_CHIP_SELECT, HIGH);

  pinMode(PIN_IMU_POWER, OUTPUT);
  digitalWrite(PIN_IMU_POWER, LOW);

  delay(10);

  pinMode(PIN_IMU_POWER, OUTPUT);
  digitalWrite(PIN_IMU_POWER, HIGH);

  delay(100); //just a little delay just in case

///////////////////////////
// This is a SPI write that occurs in ICM Library to make sure we're in bank 0 for the WhoAmI check 

  uint8_t wBuff = (0 << 4) & 0x30;
  uint8_t wReg = 127;
  uint32_t wLen = 1; 
  SPI.beginTransaction(spisettings);
  SPI.transfer(0x00);
  SPI.endTransaction();

  digitalWrite(PIN_IMU_CHIP_SELECT, LOW);
  SPI.beginTransaction(spisettings);
  SPI.transfer(((wReg & 0x7F) | 0x00));
  for (uint32_t indi = 0; indi < wLen; indi++)
  {
      SPI.transfer(*(&wBuff + indi));
  }
  SPI.endTransaction();
  digitalWrite(PIN_IMU_CHIP_SELECT, HIGH);

  delay(100); //just a little delay just in case

///////////////////////////
// This is a SPI read that occurs in ICM Library for the WhoAmI check. If all goes well we should print out 234. This checks register 0 on bank 0
// that should always return 234. Not sure why it even pulls 224, regardless of any pullups enabled.  

  uint8_t rBuff = 0x00;
  uint8_t rReg = 0;
  uint32_t rLen = 1; 

  SPI.beginTransaction(spisettings);
  SPI.transfer(0x00);
  SPI.endTransaction();

  digitalWrite(PIN_IMU_CHIP_SELECT, LOW);
  SPI.beginTransaction(spisettings);
  SPI.transfer(((rReg & 0x7F) | 0x80));
  for (uint32_t indi = 0; indi < rLen; indi++)
  {
    *(&rBuff + indi) = SPI.transfer(0x00);
  }
  SPI.endTransaction();
  digitalWrite(PIN_IMU_CHIP_SELECT, HIGH);

///////////////////////////
// Print out the WhoAmI check results

  Serial.print("Who Am I (234 is correct, 224 is not): ");
  Serial.println(rBuff);
}

void loop() {
  delay(1000); //Just some placeholder delay since all the work we need is in Setup
}

Expected behavior

Expected to get 234 when CIPO is enabled and 224 when it is disabled on both, 1.2.1 and 2.0.4 Apollo.

Actual behavior

1.2.1 works as expected, but 2.0.4 always reads 224.

PaulZC commented 3 years ago

Hi Brandon, Thanks for digging in to this! Just one very quick thought... Do you have an SD card inserted? I'm guessing you don't. But if you do, you'll (probably) need to power it up too as it shares the SPI bus with the IMU. Cheers, Paul

u382514 commented 3 years ago

Hey Paul! No, I don't have the SD card in it and I didn't seem to need it to read sensor data off the ICM using 1.2.1. I wanted to take it down to bare minimum and build back up to diagnose the issue. As you can see above with the 2.0.4 setup, it's quite a feat at the moment to get a sketch to compile. I 'think' the issue is related to CIPO because that's the only variable I've seem to be able to change that reproduces the problem but it could also very well be something deeper in 2.0.4. I'm hoping that if I can get past the 224/236 problem everything will be downhill from there!

Is there a way to test if CIPO has indeed been enabled after the code runs?

Thanks, Brandon

PaulZC commented 3 years ago

You might be able to see what is going on with an oscilloscope. I think it would need to be an oscilloscope though, a logic analyzer is unlikely to give you the full picture. You could insert a microSD Sniffer into the micro SD socket and access the CIPO signal on that? If you see the signal hitting 3.3V then you can be confident that the pull-up is enabled. All the best, Paul

u382514 commented 3 years ago

I was able to get it up and running. I needed to 'kickstart' the SPI manually BEFORE running the enableCIPOPullup logic. essentially doing below:

SPI.begin();

SPI.beginTransaction(spisettings);
SPI.transfer(0x00);
SPI.endTransaction();

am_hal_gpio_pinconfig(6, cipoPinCfg);

Once I did that I got the correct 234 whoami value and was then able to configure the ICM-20948 and read sensor data. I'm not sure why I need the kickstart here using 2.0.4 when I didn't need to do that on 1.2.1. I attempted to go down that rabbit hole and got lost. Moving forward!

Thanks!