|
| 1 | +# AMA3B1KK (Ambiq Apollo3) MCU Overview |
| 2 | + |
| 3 | +{: style="width: 50%"} |
| 4 | + |
| 5 | +The AMA3B1KK (also known as the Ambiq Apollo3 Blue) is a capable MCU with integrated Bluetooth support. It is generally available to consumers as the [Artemis Module](https://www.sparkfun.com/sparkfun-artemis-module-low-power-machine-learning-ble-cortex-m4f.html) from SparkFun, which integrates an AMA3B1KK MCU, a Bluetooth antenna, and a 32MHz crystal. |
| 6 | + |
| 7 | +| CPU | Flash/Code Memory | RAM | Communication Peripherals | Other Features | |
| 8 | +|---|---|---|---|---| |
| 9 | +| <ul><li>48-MHz Cortex M4F (hardware supports 96MHz boost, but this is not yet implemented)</li><li>Dedicated second BLE core with HCI interface (not user programmable)</li></ul> | 1 MiB Flash memory | 384 kiB SRAM | <ul><li>6x IOM (each can become an SPI or I2C instance)</li><li>2x UART</li><li>1x QSPI/OSPI (not currently supported by Mbed)</li></ol> | <ul><li>ADC with 10 muxed inputs, plus temperature sensor</li><li>16x PWM (see below)</li><li>RTC (not currently supported by Mbed)</li><li>Watchdog Timer</li><li>GPIO with interrupt capability</li></ol>| |
| 10 | + |
| 11 | +## Programming and Debugging |
| 12 | + |
| 13 | +### SVL |
| 14 | +All supported AMA3B1KK boards (except for `SFE_ARTEMIS_DK`) rely on the SparkFun Variable Loader (SVL) to upload code without a dedicated programmer/debugger. This is described in more detail on the [upload methods page](../upload-methods.md#ambiq-svl), and is easy to set up (it's bundled with Mbed!). |
| 15 | + |
| 16 | +### Serial Port Reset Circuit |
| 17 | + |
| 18 | +In order for SVL to work, there needs to be a way for the host machine to reset the MCU. This has been implemented by connecting the serial port DTR control line to the MCU reset line via a low-pass filter (see below). |
| 19 | + |
| 20 | + |
| 21 | + |
| 22 | +When the serial port is opened, DTR goes low, and the MCU is pulled into reset. Then, R3 charges the reset line back up, and around 100us later, the AMA3B1KK is released from reset. |
| 23 | + |
| 24 | +In many ways, this is a clever idea, as it allows resetting the chip without involvement from SW on the chip (which might not be working), but also doesn't require the serial terminal to bring DTR high again to take the chip out of reset (I made that mistake once!). |
| 25 | + |
| 26 | +However, this does have a side effect that users should watch out for. Opening a serial terminal to the board will **always reset the chip**, wiping away whatever it was previously doing! |
| 27 | + |
| 28 | +### Boot Differences with the Bootloader |
| 29 | +In my testing, I've observed that it takes around 300ms for the SVL bootloader to transfer control to the application after power is released. This is a long delay, and necessitated an adjustment to Mbed OS's CI test scripts to wait longer after opening the serial port before trying to talk to the chip. It appears that this delay is mostly due to a sleep inside the bootloader that waits for a host PC to try to talk to it before running the application. |
| 30 | + |
| 31 | +Also, there appears to be a logic glitch that occurs when the chip boots which can often manifest as a junk byte (and therefore a unicode decode error) on the serial output. I do not know the cause of this, but it is mentioned in SparkFun's documentation, so it appears to be a known issue. |
| 32 | + |
| 33 | +### Debugging |
| 34 | + |
| 35 | +AMA3B1KK is supported by the J-Link and PyOCD debuggers. The former requires J-Link hardware, while the latter will work with any CMSIS-DAP device. Personally, I experienced silky smooth debugging by attaching a PicoProbe to the SWD pins on my RedBoard Artemis (by cutting the debug ribbon cable, stripping the wires, and feeding them through the fine pitch holes). |
| 36 | + |
| 37 | +Also, one board, the [Artemis Development Kit](https://www.sparkfun.com/sparkfun-artemis-development-kit.html), does have a built-in CMSIS-DAP debugger. I'd recommend getting this board if you plan to be debugging code! |
| 38 | + |
| 39 | +## Clock Sources |
| 40 | + |
| 41 | +The AMA3B1KK has a total of four clock sources: |
| 42 | + |
| 43 | +1. The High Frequency RC Oscillator (HFRC), which is an internal oscillator that creates 96MHz and 48MHz for the CPU and its peripherals |
| 44 | + - This has a base accuracy of +-3.5%, but can auto calibrate itself based on the XT crystal frequency. |
| 45 | + - I haven't been able to find an official spec for how much the calibration improves its accuracy, but in my testing it made it accurate to about +-0.1% |
| 46 | +2. The 32MHz Crystal Oscillator (XO32M), which creates a high-accuracy 32MHz clock for the bluetooth radio. This crystal is contained inside the Artemis module and doesn't need to be added to the board. |
| 47 | +3. The 32.768kHz Crystal Oscillator (XT), which creates a 32.768kHz clock for a number of sources inside the Apollo3, including the LP Ticker and the RTC. It's also used to calibrate the HFRC. |
| 48 | +4. The Low Frequency RC Oscillator (LFRC), which is a 1024Hz +-32% internal oscillator. It can be used as a fallback if other clock sources are not present (and for creating very, very slow PWM signals). |
| 49 | + |
| 50 | +Having only an RC oscillator (albeit one with a calibration feature) is unusual among ARM MCUs, and means that high speed clocks and counters driven by them (e.g. Mbed's μs ticker) will be relatively inaccurate. Luckily, more accuracy is present in the XT oscillator, which drives the Low Precision Ticker and the Real-Time Clock. Mbed also turns on the HFRC calibration feature, meaning that the XT frequency will be used to automatically tune the HFRC. This means that within a few seconds after boot, the HFRC frequency should become significantly more accurate. |
| 51 | + |
| 52 | +Note that since the XT clock is used to calibrate the HFRC and drive certain timers, Mbed does not recommend omitting the XT crystal in designs with this chip. |
| 53 | + |
| 54 | +## Other Notes |
| 55 | + |
| 56 | +### Timer Usage by Mbed |
| 57 | +Mbed OS manages the `STIMER` peripheral and uses it to implement the μs ticker. It is not recommended to use this peripheral in user code. Use Mbed OS Timers and Tickers instead. |
| 58 | + |
| 59 | +Mbed OS uses both segments of `CTIMER_7` to implement the Low Precision Ticker. This means that this timer is not available for PWM or timing purposes. |
| 60 | + |
| 61 | +### GPIO Naming |
| 62 | +Unusually, the AMA3B1KK does not have its GPIOs organized into ports. It simply has 50 I/O pins, numbered from 0 to 49. Mbed refers to these as `IO_x`, e.g. `IO_0` and `IO_25`. |
| 63 | + |
| 64 | +### PWM Assignment |
| 65 | +We have lots of PWMs to work with here! The AMA3B1KK has 8 CTIMER modules, each of which has two independent segments that can each generate two PWM outputs (with the same frequency but different duty cycles). This gives 32 total outputs, and there are 32 pins that can be mapped to PWM, giving a 1:1 mapping. |
| 66 | + |
| 67 | +However, both segments of CTIMER_7 are used by the LP ticker. This means that the chip effectively has 28 PWMs spread across the 32 pins, though each pair of two PWMs on the same segment must use the same frequency. |
| 68 | + |
| 69 | +To see which pins are paired with each other, look [here](https://github.com/mbed-ce/mbed-os/blob/95138e4d6a756c72a87cc87a6a87cae4b40d47eb/targets/TARGET_Ambiq_Micro/TARGET_Apollo3/device/PeripheralPins.c#L275). For example, since IO_12 and IO_25 both use CTIMER_A0, they must have the same frequency set in order to work. |
| 70 | + |
| 71 | +### Internal Temperature Sensor |
| 72 | + |
| 73 | +The AMA3B1KK features an internal temperature sensor which is connected to one of the ADC inputs. You can read this temp sensor by constructing an `AnalogIn` with `INT_TEMP_SENSOR` as the pin name. |
| 74 | + |
| 75 | +To convert the value from volts to degrees, however, you must use a function from the Ambiq SDK which reads the calibration constants burned into the chip at the factory. And this function has an... interesting... calling convention. |
| 76 | + |
| 77 | +To get you started, here's an example (based on [here](https://github.com/sparkfun/Arduino_Apollo3/blob/74a4786eef78e0457548d43e23366a20dfa4410e/cores/arduino/sdk/core-implement/CommonAnalog.cpp#L55)): |
| 78 | + |
| 79 | +```cpp |
| 80 | +float getTempDegC() { |
| 81 | + static AnalogIn intTempSensor(INT_TEMP_SENSOR); |
| 82 | + float tempSensorVolts = intTempSensor.read_voltage(); |
| 83 | + |
| 84 | + float fVT[3]; |
| 85 | + fVT[0] = tempSensorVolts; |
| 86 | + fVT[1] = 0.0f; |
| 87 | + fVT[2] = -123.456; |
| 88 | + uint32_t ui32Retval = am_hal_adc_control(am_adc_handle, AM_HAL_ADC_REQ_TEMP_CELSIUS_GET, fVT); |
| 89 | + MBED_ASSERT(ui32Retval == AM_HAL_STATUS_SUCCESS); |
| 90 | + |
| 91 | + return fVT[1]; // Get the temperature |
| 92 | +} |
| 93 | +``` |
| 94 | + |
| 95 | +### Analog Reference Voltage |
| 96 | + |
| 97 | +The AMA3B1KK has a several options for analog voltage references: an internal 1.5V +-1.7% reference, an internal 2.0V +-1.5% reference, and an external reference provided on the ADC_REF pin (which can be either 1.5V or 2V). |
| 98 | + |
| 99 | +Currently, Mbed OS hardcodes usage of the 2V reference to provide the maximum possible analog range. This means that analog in pins can **only measure voltages between 0V and 2V**, not the full 3.3V I/O voltage range! |
| 100 | + |
| 101 | +Also note that ADC_REF is not pinned out on the Artemis module, so it's impossible to use the external ADC reference with this hardware. |
0 commit comments