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

Feature: Support for Ambiq Apollo 3 #1587

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions meson_options.txt
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ option(
'cortexm',
'riscv32',
'riscv64',
'apollo3',
'at32f4',
'ch579',
'efm',
Expand Down
1 change: 1 addition & 0 deletions src/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ SRC = \
adiv5.c \
adiv5_jtag.c \
adiv5_swd.c \
apollo3.c \
adiv6.c \
command.c \
cortex.c \
Expand Down
140 changes: 140 additions & 0 deletions src/target/apollo3.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
/*
* This file is part of the Black Magic Debug project.
*
* Copyright (C) 2022-2023 1BitSquared <[email protected]>
* Written by Sid Price <[email protected]>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

#include "general.h"
#include "target.h"
#include "target_internal.h"

static bool apollo_3_flash_erase(target_flash_s *flash, target_addr_t addr, size_t len);
static bool apollo_3_flash_write(target_flash_s *flash, target_addr_t dest, const void *src, size_t len);

#define APOLLO_3_FLASH_BASE_ADDRESS 0x00000000U
#define APOLLO_3_FLASH_SIZE 0x00100000U
#define APOLLO_3_FLASH_BLOCK_SIZE 0x2000U

#define APOLLO_3_SRAM_BASE 0x10000000U
#define APOLLO_3_SRAM_SIZE 0x00060000U

#define APOLLO_3_CHIPPN_REGISTER 0x40020000U /* Address of the Chip Part Number Register */

/*
Define the bitfields of the CHIPPN register.

This register contains the part number of the MCU
*/
#define APOLLO_3_CHIPPN_PART_NUMBER_MASK 0xff000000U
#define APOLLO_3_CHIPPN_PART_NUMBER_BIT_POSITION 0x18U

#define APOLLO_3_CHIPPN_FLASH_SIZE_MASK 0x00f00000U
#define APOLLO_3_CHIPPN_FLASH_SIZE_BIT_POSITION 0x14U

#define APOLLO_3_CHIPPN_SRAM_SIZE_MASK 0x000f0000U
#define APOLLO_3_CHIPPN_SRAM_SIZE_BIT_POSITION 0x10U

#define APOLLO_3_CHIPPN_REVISION_MASK 0x0000ff00U
#define APOLLO_3_CHIPPN_REVISION_BIT_POSITION 0x08U

#define APOLLO_3_CHIPPN_PACKAGE_MASK 0x000000c0U
#define APOLLO_3_CHIPPN_PACKAGE_BIT_POSITION 0x06U

#define APOLLO_3_CHIPPN_PINS_MASK 0x00000038U
#define APOLLO_3_CHIPPN_PINS_BIT_POSITION 0x03U

#define APOLLO_3_CHIPPN_TEMP_MASK 0x00000006U
#define APOLLO_3_CHIPPN_TEMP_BIT_POSITION 0x01U

#define APOLLO_3_CHIPPN_QUALIFIED_MASK 0x00000001U
#define APOLLO_3_CHIPPN_QUALIFIED_BIT_POSITION 0x0U

#define APOLLO_3_CHIPID0_REGISTER 0x40020004U /* Chip ID Register 0 */
#define APOLLO_3_CHIPID1_REGISTER 0x40020008U /* Chip ID Register 1 */

#define APOLLO_3_CHIPREV_REGISTER 0x4002000cU /* Chip Revision Register */

/*
dragonmux marked this conversation as resolved.
Show resolved Hide resolved
Define the bitfields of the CHIPREV register.

This register contains the revision of the MCU
*/
#define APOLLO_3_CHIPREV_RESERVED 0xfff00000U
#define APOLLO_3_CHIPREV_SI_PART 0x000fff00U
#define APOLLO_3_CHIPREV_REVMAJ 0x000000f0U
#define APOLLO_3_CHIPREV_REVMIN 0x0000000fU

#define APOLLO_3_VENDOR_ID_ADDRESS 0x40020010U /* Vendor ID Register */
#define APOLLO_3_VENDOR_ID 0x414d4251U

static void apollo_3_add_flash(target_s *target)
{
target_flash_s *flash = calloc(1, sizeof(*flash));
if (!flash) { /* calloc failed: heap exhaustion */
DEBUG_WARN("calloc: failed in %s\n", __func__);
return;
}

flash->start = APOLLO_3_FLASH_BASE_ADDRESS;
flash->length = APOLLO_3_FLASH_SIZE;
flash->blocksize = APOLLO_3_FLASH_BLOCK_SIZE;
flash->erase = apollo_3_flash_erase;
flash->write = apollo_3_flash_write;
flash->erased = 0xffU;
target_add_flash(target, flash);
}

bool apollo_3_probe(target_s *target)
{
uint32_t mcu_vendor_id = target_mem32_read32(target, APOLLO_3_VENDOR_ID_ADDRESS);
if (mcu_vendor_id != APOLLO_3_VENDOR_ID) {
DEBUG_INFO("Invalid vendor ID read\n");
return false;
} else
DEBUG_INFO("Read correct vendor ID\n");
/* Read the CHIPPN register to gather MCU details */
uint32_t mcu_chip_partnum = target_mem32_read32(target, APOLLO_3_CHIPPN_REGISTER);
/* Check the chip is an Apollo 3 */
if ((mcu_chip_partnum & APOLLO_3_CHIPPN_PART_NUMBER_MASK) != 0x06000000) {
DEBUG_INFO("Invalid chip type read\n");
return false;
}

target->driver = "Apollo 3 Blue";

target_add_ram32(target, APOLLO_3_SRAM_BASE, APOLLO_3_SRAM_SIZE);

apollo_3_add_flash(target);
return true;
}

static bool apollo_3_flash_erase(target_flash_s *flash, target_addr_t addr, size_t len)
{
(void)flash;
(void)addr;
(void)len;
return false;
}

static bool apollo_3_flash_write(target_flash_s *flash, target_addr_t dest, const void *src, size_t len)
{
(void)flash;
(void)dest;
(void)src;
(void)len;
return false;
}
1 change: 1 addition & 0 deletions src/target/cortexm.c
Original file line number Diff line number Diff line change
Expand Up @@ -656,6 +656,7 @@ bool cortexm_probe(adiv5_access_port_s *ap)
} else if (target->part_id == 0x4c4U) { /* Cortex-M4 ROM */
PROBE(sam3x_probe);
PROBE(lmi_probe);
PROBE(apollo_3_probe);
/*
* The LPC546xx and LPC43xx parts present with the same AP ROM part number,
* so we need to probe both. Unfortunately, when probing for the LPC43xx
Expand Down
7 changes: 7 additions & 0 deletions src/target/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ if is_firmware_build
'riscv32': 'RISC-V 32-bit support',
'riscv64': 'RISC-V 64-bit support',
'at32f4': 'Arterytek parts',
'apollo3': 'Ambiq Apollo3 parts',
'ch579': 'CH579',
'efm': 'Energy Micro parts',
'hc32': 'HC32 parts',
Expand Down Expand Up @@ -157,6 +158,11 @@ target_riscv64 = declare_dependency(
dependencies: target_riscv,
)

target_apollo3 = declare_dependency(
sources: files('apollo3.c'),
dependencies: target_cortexm,
)

target_ch579 = declare_dependency(
sources: files('ch579.c'),
dependencies: target_cortexm,
Expand Down Expand Up @@ -320,6 +326,7 @@ libbmd_target_deps = [
target_riscv32,
target_riscv64,
# Enable all targets for libbmd
target_apollo3,
target_at32f4,
target_ch579,
target_efm,
Expand Down
1 change: 1 addition & 0 deletions src/target/target_probe.c
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ CORTEXM_PROBE_WEAK_NOP(lpc55_dmap_probe)
CORTEXM_PROBE_WEAK_NOP(nrf51_mdm_probe)
CORTEXM_PROBE_WEAK_NOP(rp_rescue_probe)

TARGET_PROBE_WEAK_NOP(apollo_3_probe)
TARGET_PROBE_WEAK_NOP(at32f40x_probe)
TARGET_PROBE_WEAK_NOP(at32f43x_probe)
TARGET_PROBE_WEAK_NOP(ch32f1_probe)
Expand Down
1 change: 1 addition & 0 deletions src/target/target_probe.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ bool nrf51_mdm_probe(adiv5_access_port_s *ap);
bool rp_rescue_probe(adiv5_access_port_s *ap);

bool at32f40x_probe(target_s *target); // STM32 clones from Artery
bool apollo_3_probe(target_s *target);
bool at32f43x_probe(target_s *target);
bool ch32f1_probe(target_s *target); // will catch all the clones
bool ch579_probe(target_s *target);
Expand Down
Loading