Cannot connect to Artemis Module over BLE

I uploaded the “Example11_BLEAdvertise” program to an Artemis Module mounted on a custom PCB. The module goes into advertising mode, but I am unable to connect. It seems to be on about a 10 second cycle where it connects and disconnects (See serial output below). I’ve also attached to IDE output below. Can anyone help with this? The same code uploads to an Artemis RedBoard fine and holds the connection. One thing I realized is that I am missing the crystal oscilator circuit that the redboard has (connection between XO and XI pins). Could this cause the issue?

For reference, I’m using SparkFun Apollo Boards v 2.2.1, Arduino API v 1.8.19 and arduinoBLE v1.3.1, though I have tried several other version combinations.

Thank you.

BLE advertising as ‘Artemis’

12:05:31.328 → Connected to central: 64:af:c8:c9:ff:cf

12:05:32.056 → Disconnected from central: 64:af:c8:c9:ff:cf

12:06:20.931 → Connected to central: 64:af:c8:c9:ff:cf

12:06:21.666 → Disconnected from central: 64:af:c8:c9:ff:cf

12:06:43.015 → Connected to central: 64:af:c8:c9:ff:cf

12:06:43.717 → Disconnected from central: 64:af:c8:c9:ff:cf

12:07:05.665 → Connected to central: 64:af:c8:c9:ff:cf

12:07:06.377 → Disconnected from central: 64:af:c8:c9:ff:cf

12:07:25.352 → Connected to central: 64:af:c8:c9:ff:cf

12:07:26.046 → Disconnected from central: 64:af:c8:c9:ff:cf

12:07:35.149 → Connected to central: 64:af:c8:c9:ff:cf

12:07:35.829 → Disconnected from central: 64:af:c8:c9:ff:cf

12:07:53.523 → Connected to central: 64:af:c8:c9:ff:cf

12:07:54.230 → Disconnected from central: 64:af:c8:c9:ff:cf

12:20:00.176 → ⸮

12:20:30.638 → ++ MbedOS Fault Handler ++

12:20:30.638 →

12:20:30.638 → FaultType: HardFault

12:20:30.638 →

12:20:30.638 → Context:

12:20:30.638 → R0: 0

12:20:30.638 → R1: 0

12:20:30.638 → R2: 3

12:20:30.638 → R3: 146F9

12:20:30.638 → R4: 1000102C

12:20:30.638 → R5: 10001050

12:20:30.638 → R6: FFFFFFFF

12:20:30.638 → R7: 0

12:20:30.638 → R8: 0

12:20:30.638 → R9: 0

12:20:30.638 → R10: 0

12:20:30.638 → R11: 0

12:20:30.638 → R12: 0

12:20:30.638 → SP : 10006F20

12:20:30.638 → LR : 14703

12:20:30.638 → PC : 10F2C

12:20:30.638 → xPSR : 1000000

12:20:30.638 → PSP : 10006F00

12:20:30.638 → MSP : 1005FF70

12:20:30.638 → CPUID: 410FC241

12:20:30.676 → HFSR : 40000000

12:20:30.676 → MMFSR: 0

12:20:30.676 → BFSR : 82

12:20:30.676 → UFSR : 0

12:20:30.676 → DFSR : 0

12:20:30.676 → AFSR : 0

12:20:30.676 → BFAR : 1C

12:20:30.676 → Mode : Thread

12:20:30.676 → Priv : Privileged

12:20:30.676 → Stack: PSP

12:20:30.676 →

12:20:30.676 → – MbedOS Fault Handler –

12:20:30.676 →

12:20:30.676 →

12:20:30.676 →

12:20:30.676 → ++ MbedOS Error Info ++

12:20:30.676 → Error Status: 0x80FF013D Code: 317 Module: 255

12:20:30.676 → Error Message: Fault exception

12:20:30.676 → Location: 0x10F2C

12:20:30.676 → Error Value: 0x10005F10

12:20:30.676 → Current Thread: main Id: 0x100044B0 Entry: 0x28DDD StackSize: 0x1000 StackMem: 0x10005F70 SP: 0x10006F20

12:20:30.676 → For more info, visit: https://mbed.com/s/error?error=0x80FF01 … MIS_MODULE

12:20:30.710 → – MbedOS Error Info –

Artemis SVL Bootloader

Script version 1.7

Phase: Setup

Cleared startup blip

Got SVL Bootloader Version: 5

Sending ‘enter bootloader’ command

Phase: Bootload

have 151136 bytes to send in 74 frames

Sending frame #1, length: 2048

Sending frame #2, length: 2048

Sending frame #3, length: 2048

Sending frame #4, length: 2048

Sending frame #5, length: 2048

Sending frame #6, length: 2048

Sending frame #7, length: 2048

Sending frame #8, length: 2048

Sending frame #9, length: 2048

Sending frame #10, length: 2048

Sending frame #11, length: 2048

Sending frame #12, length: 2048

Sending frame #13, length: 2048

Sending frame #14, length: 2048

Sending frame #15, length: 2048

Sending frame #16, length: 2048

Sending frame #17, length: 2048

Sending frame #18, length: 2048

Sending frame #19, length: 2048

Sending frame #20, length: 2048

Sending frame #21, length: 2048

Sending frame #22, length: 2048

Sending frame #23, length: 2048

Retrying…

Sending frame #23, length: 2048

Sending frame #24, length: 2048

Sending frame #25, length: 2048

Sending frame #26, length: 2048

Sending frame #27, length: 2048

Sending frame #28, length: 2048

Sending frame #29, length: 2048

Sending frame #30, length: 2048

Sending frame #31, length: 2048

Sending frame #32, length: 2048

Sending frame #33, length: 2048

Sending frame #34, length: 2048

Sending frame #35, length: 2048

Sending frame #36, length: 2048

Sending frame #37, length: 2048

Sending frame #38, length: 2048

Sending frame #39, length: 2048

Sending frame #40, length: 2048

Sending frame #41, length: 2048

Sending frame #42, length: 2048

Sending frame #43, length: 2048

Sending frame #44, length: 2048

Sending frame #45, length: 2048

Sending frame #46, length: 2048

Sending frame #47, length: 2048

Sending frame #48, length: 2048

Sending frame #49, length: 2048

Sending frame #50, length: 2048

Retrying…

Sending frame #50, length: 2048

Sending frame #51, length: 2048

Sending frame #52, length: 2048

Sending frame #53, length: 2048

Sending frame #54, length: 2048

Sending frame #55, length: 2048

Sending frame #56, length: 2048

Sending frame #57, length: 2048

Sending frame #58, length: 2048

Sending frame #59, length: 2048

Sending frame #60, length: 2048

Sending frame #61, length: 2048

Sending frame #62, length: 2048

Sending frame #63, length: 2048

Sending frame #64, length: 2048

Sending frame #65, length: 2048

Sending frame #66, length: 2048

Sending frame #67, length: 2048

Sending frame #68, length: 2048

Sending frame #69, length: 2048

Sending frame #70, length: 2048

Sending frame #71, length: 2048

Sending frame #72, length: 2048

Sending frame #73, length: 2048

Sending frame #74, length: 1632

Upload complete

Nominal bootload bps: 27344.55

sorry for the late reaction (vacation time :slight_smile: )

Looking at the clock generator in the datasheet, the 32Khz for the BLE is coming from the external XTAL. The 32Khz can also be used to generate XT-x frequency sources that can be used by other components in the Apollo3 (e.g. the RTC) In the past I had found for Apollo2 the attached document related to the XTAL.

Also for different versions of the Apollo3 chip patches can be applied on BLE. (although these are hard to understand) You can check your Apollo3 chip version with the sketch below.

#include "am_util_id.h"

//*****************************************************************************
//
// Chip Revision IDentification.
// source:  am_hal_mcuctrl.h
//*****************************************************************************
#define APOLLO3_B0                                                          \
        ((MCUCTRL->CHIPREV  &                                               \
           (MCUCTRL_CHIPREV_REVMAJ_Msk | MCUCTRL_CHIPREV_REVMIN_Msk)) ==    \
           (_VAL2FLD(MCUCTRL_CHIPREV_REVMAJ, MCUCTRL_CHIPREV_REVMAJ_B) |    \
            _VAL2FLD(MCUCTRL_CHIPREV_REVMIN, MCUCTRL_CHIPREV_REVMIN_REV0)))

#define APOLLO3_A1                                                          \
        ((MCUCTRL->CHIPREV  &                                               \
           (MCUCTRL_CHIPREV_REVMAJ_Msk | MCUCTRL_CHIPREV_REVMIN_Msk)) ==    \
           (_VAL2FLD(MCUCTRL_CHIPREV_REVMAJ, MCUCTRL_CHIPREV_REVMAJ_A) |    \
            _VAL2FLD(MCUCTRL_CHIPREV_REVMIN, MCUCTRL_CHIPREV_REVMIN_REV1)))

#define APOLLO3_A0                                                          \
        ((MCUCTRL->CHIPREV  &                                               \
           (MCUCTRL_CHIPREV_REVMAJ_Msk | MCUCTRL_CHIPREV_REVMIN_Msk)) ==    \
           (_VAL2FLD(MCUCTRL_CHIPREV_REVMAJ, MCUCTRL_CHIPREV_REVMAJ_A) |    \
            _VAL2FLD(MCUCTRL_CHIPREV_REVMIN, MCUCTRL_CHIPREV_REVMIN_REV0)))

//
// Determine if >= a given revision level.
// source:  am_hal_mcuctrl.h
//

#define APOLLO3_GE_B0                                                       \
        ((MCUCTRL->CHIPREV  &                                               \
           (MCUCTRL_CHIPREV_REVMAJ_Msk | MCUCTRL_CHIPREV_REVMIN_Msk)) >=    \
           (_VAL2FLD(MCUCTRL_CHIPREV_REVMAJ, MCUCTRL_CHIPREV_REVMAJ_B) |    \
            _VAL2FLD(MCUCTRL_CHIPREV_REVMIN, MCUCTRL_CHIPREV_REVMIN_REV0)))

#define APOLLO3_GE_A1                                                       \
        ((MCUCTRL->CHIPREV  &                                               \
           (MCUCTRL_CHIPREV_REVMAJ_Msk | MCUCTRL_CHIPREV_REVMIN_Msk)) >=    \
           (_VAL2FLD(MCUCTRL_CHIPREV_REVMAJ, MCUCTRL_CHIPREV_REVMAJ_A) |    \
            _VAL2FLD(MCUCTRL_CHIPREV_REVMIN, MCUCTRL_CHIPREV_REVMIN_REV1)))


void setup() {
  
  am_util_id_t info;

  Serial.begin(115200);

  Serial.println("get device info");

  uint32_t dev = am_util_id_device(&info);

  if (dev == AM_UTIL_ID_APOLLO) {
    Serial.println("device is AM_UTIL_ID_APOLLO");
  }
  else  if (dev == AM_UTIL_ID_APOLLO2) {
    Serial.println("device is AM_UTIL_ID_APOLLO2");
  }
  else  if (dev == AM_UTIL_ID_APOLLO3) {
    Serial.println("device is AM_UTIL_ID_APOLLO3");
  }
  else if (dev == AM_UTIL_ID_APOLLO3P) {
    Serial.println("device is AM_UTIL_ID_APOLLO3P");
  }
  else
    Serial.println ("Unkown");

  Serial.print ("Major revision ");
  Serial.println((char) info.ui8ChipRevMaj);

  Serial.print ("Minor revision ");
  Serial.println((char) info.ui8ChipRevMin);

  if (APOLLO3_B0) {
    Serial.println("APOLLO3_B0");
  }
  else if (APOLLO3_A0) {
    Serial.println("APOLLO3_A0");
  }
  else if (APOLLO3_A1) {
    Serial.println("APOLLO3_A1");
  }
  else
  {  
    Serial.println("Apollo3_ version unknown");
  }

//
// Determine if >= a given revision level.
//
 if (APOLLO3_GE_B0) {
    Serial.println("APOLLO3_GE_B0");
  }
  else if (APOLLO3_GE_A1) {
    Serial.println("APOLLO3_GE_A1");
  }
 
}

void loop() {
  // put your main code here, to run repeatedly:

}

Design_Guidelines_for_Apollo2_rev1_1.pdf (1.29 MB)

Thank you, Paul. That was helpful. For anybody who may have this problem in the future, adding the XTAL circuit resolved the issue.

paulvha:
sorry for the late reaction (vacation time :slight_smile: )

Looking at the clock generator in the datasheet, the 32Khz for the BLE is coming from the external XTAL. The 32Khz can also be used to generate XT-x frequency sources that can be used by other components in the Apollo3 (e.g. the RTC) In the past I had found for Apollo2 the attached document related to the XTAL.

Also for different versions of the Apollo3 chip patches can be applied on BLE. (although these are hard to understand) You can check your Apollo3 chip version with the sketch below.

#include "am_util_id.h"

//*****************************************************************************
//
// Chip Revision IDentification.
// source: am_hal_mcuctrl.h
//*****************************************************************************
#define APOLLO3_B0
((MCUCTRL->CHIPREV &
(MCUCTRL_CHIPREV_REVMAJ_Msk | MCUCTRL_CHIPREV_REVMIN_Msk)) ==
(_VAL2FLD(MCUCTRL_CHIPREV_REVMAJ, MCUCTRL_CHIPREV_REVMAJ_B) |
_VAL2FLD(MCUCTRL_CHIPREV_REVMIN, MCUCTRL_CHIPREV_REVMIN_REV0)))

#define APOLLO3_A1
((MCUCTRL->CHIPREV &
(MCUCTRL_CHIPREV_REVMAJ_Msk | MCUCTRL_CHIPREV_REVMIN_Msk)) ==
(_VAL2FLD(MCUCTRL_CHIPREV_REVMAJ, MCUCTRL_CHIPREV_REVMAJ_A) |
_VAL2FLD(MCUCTRL_CHIPREV_REVMIN, MCUCTRL_CHIPREV_REVMIN_REV1)))

#define APOLLO3_A0
((MCUCTRL->CHIPREV &
(MCUCTRL_CHIPREV_REVMAJ_Msk | MCUCTRL_CHIPREV_REVMIN_Msk)) ==
(_VAL2FLD(MCUCTRL_CHIPREV_REVMAJ, MCUCTRL_CHIPREV_REVMAJ_A) |
_VAL2FLD(MCUCTRL_CHIPREV_REVMIN, MCUCTRL_CHIPREV_REVMIN_REV0)))

//
// Determine if >= a given revision level.
// source: am_hal_mcuctrl.h
//

#define APOLLO3_GE_B0
((MCUCTRL->CHIPREV &
(MCUCTRL_CHIPREV_REVMAJ_Msk | MCUCTRL_CHIPREV_REVMIN_Msk)) >=
(_VAL2FLD(MCUCTRL_CHIPREV_REVMAJ, MCUCTRL_CHIPREV_REVMAJ_B) |
_VAL2FLD(MCUCTRL_CHIPREV_REVMIN, MCUCTRL_CHIPREV_REVMIN_REV0)))

#define APOLLO3_GE_A1
((MCUCTRL->CHIPREV &
(MCUCTRL_CHIPREV_REVMAJ_Msk | MCUCTRL_CHIPREV_REVMIN_Msk)) >=
(_VAL2FLD(MCUCTRL_CHIPREV_REVMAJ, MCUCTRL_CHIPREV_REVMAJ_A) |
_VAL2FLD(MCUCTRL_CHIPREV_REVMIN, MCUCTRL_CHIPREV_REVMIN_REV1)))

void setup() {

am_util_id_t info;

Serial.begin(115200);

Serial.println(“get device info”);

uint32_t dev = am_util_id_device(&info);

if (dev == AM_UTIL_ID_APOLLO) {
Serial.println(“device is AM_UTIL_ID_APOLLO”);
}
else if (dev == AM_UTIL_ID_APOLLO2) {
Serial.println(“device is AM_UTIL_ID_APOLLO2”);
}
else if (dev == AM_UTIL_ID_APOLLO3) {
Serial.println(“device is AM_UTIL_ID_APOLLO3”);
}
else if (dev == AM_UTIL_ID_APOLLO3P) {
Serial.println(“device is AM_UTIL_ID_APOLLO3P”);
}
else
Serial.println (“Unkown”);

Serial.print ("Major revision ");
Serial.println((char) info.ui8ChipRevMaj);

Serial.print ("Minor revision ");
Serial.println((char) info.ui8ChipRevMin);

if (APOLLO3_B0) {
Serial.println(“APOLLO3_B0”);
}
else if (APOLLO3_A0) {
Serial.println(“APOLLO3_A0”);
}
else if (APOLLO3_A1) {
Serial.println(“APOLLO3_A1”);
}
else
{
Serial.println(“Apollo3_ version unknown”);
}

//
// Determine if >= a given revision level.
//
if (APOLLO3_GE_B0) {
Serial.println(“APOLLO3_GE_B0”);
}
else if (APOLLO3_GE_A1) {
Serial.println(“APOLLO3_GE_A1”);
}

}

void loop() {
// put your main code here, to run repeatedly:

}