Skip to content

Commit

Permalink
stm32f1: Add product IDs for AT32F413, AT32F421
Browse files Browse the repository at this point in the history
* and rename at32f41_detect to AT32F415 for what it is
  • Loading branch information
ALTracer committed Sep 29, 2024
1 parent fd32bf6 commit 9cfa5f3
Showing 1 changed file with 112 additions and 5 deletions.
117 changes: 112 additions & 5 deletions src/target/stm32f1.c
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,12 @@
#define AT32F4x_IDCODE_PART_MASK 0x00000fffU
#define AT32F41_SERIES 0x70030000U
#define AT32F40_SERIES 0x70050000U
#define AT32F421_SERIES_16KB 0x50010000U
#define AT32F421_SERIES 0x50020000U
#define AT32F405_SERIES 0x70053000U
#define AT32F402_SERIES 0x70042000U
#define AT32F4x_PROJECT_ID 0x1ffff7f3U
#define AT32F4x_FLASHSIZE 0x1ffff7e0U

#define STM32F1_FLASH_BANK1_BASE 0x08000000U
#define STM32F1_FLASH_BANK2_BASE 0x08080000U
Expand Down Expand Up @@ -420,11 +426,13 @@ static bool at32f40_detect(target_s *target, const uint16_t part_id)

// AT32F403A/F407 have 48 bytes of User System Data
target_add_commands(target, stm32f1_cmd_list, target->driver);
// TODO: SPIM 0x08400000 bank support

/* Now we have a stable debug environment, make sure the WDTs + WFI and WFE instructions can't cause problems */
return stm32f1_configure_dbgmcu(target, STM32F1_DBGMCU_CONFIG);
}

static bool at32f41_detect(target_s *target, const uint16_t part_id)
static bool at32f415_detect(target_s *target, const uint16_t part_id)
{
switch (part_id) {
case 0x0240U: // LQFP64_10x10
Expand Down Expand Up @@ -459,11 +467,98 @@ static bool at32f41_detect(target_s *target, const uint16_t part_id)
target->part_id = part_id;
target->target_options |= STM32F1_TOPT_32BIT_WRITES;
target->mass_erase = stm32f1_mass_erase;
// TODO: 1 KiB User System Data, i.e. Option bytes

/* Now we have a stable debug environment, make sure the WDTs + WFI and WFE instructions can't cause problems */
return stm32f1_configure_dbgmcu(target, STM32F1_DBGMCU_CONFIG);
}

static bool at32f413_detect(target_s *target, const uint16_t part_id)
{
switch (part_id) {
case 0x0240U: // LQFP64
case 0x0242U: // LQFP48
case 0x0244U: // QFN32
case 0x0247U: // QFN48
// Flash (C): 256 KiB / 2 KiB per block
stm32f1_add_flash(target, 0x08000000, 256U * 1024U, 2U * 1024U);
break;
case 0x01c1U: // LQFP64
case 0x01c3U: // LQFP48
case 0x01c5U: // QFN32
case 0x01caU: // QFN48
// Flash (B): 128 KiB / 1 KiB per block
stm32f1_add_flash(target, 0x08000000, 128U * 1024U, 1U * 1024U);
break;
case 0x0106U: // LQFP48
// Flash (8): 64 KiB / 1 KiB per block
stm32f1_add_flash(target, 0x08000000, 64U * 1024U, 1U * 1024U);
break;
// Unknown/undocumented
default:
return false;
}
// All parts have 32 KiB of SRAM extensible by EOPB0 up to 64 KiB or down to 16 KiB
target_add_ram32(target, 0x20000000, 32U * 1024U);
target->driver = "AT32F413";
target->part_id = part_id;
target->target_options |= STM32F1_TOPT_32BIT_WRITES;
target->mass_erase = stm32f1_mass_erase;
// TODO: AT32F413 have 48 bytes of User System Data
// TODO: SPIM 0x08400000 bank support
return stm32f1_configure_dbgmcu(target, STM32F1_DBGMCU_CONFIG);
}

static bool at32f421_detect(target_s *target, const uint16_t part_id)
{
// Extra part: AT32F4212C8T7 with dual Op-Amp? (16/64, LQFP48)
switch (part_id) {
case 0x0100U: // AT32F421C8T7 / LQFP48
case 0x0101U: // AT32F421K8T7 / LQFP32
case 0x0102U: // AT32F421K8U7 / QFN32_5x5
case 0x0103U: // AT32F421K8U7-4 / QFN32_4x4
case 0x0104U: // AT32F421F8U7 / QFN20
case 0x0105U: // AT32F421F8P7 / TSSOP20
case 0x0112U: // AT32F421G8U7 / QFN28
// Flash (8): 64 KiB / 1 KiB per block
stm32f1_add_flash(target, 0x08000000, 64U * 1024U, 1U * 1024U);
target_add_ram32(target, 0x20000000, 16U * 1024U);
break;
case 0x0086U: // LQFP48
case 0x0087U: // LQFP32
case 0x0088U: // QFN32_5x5
case 0x0089U: // QFN32_4x4
case 0x008aU: // QFN20
case 0x008bU: // TSSOP20
case 0x0093U: // QFN28
// Flash (6): 32 KiB / 1 KiB per block
stm32f1_add_flash(target, 0x08000000, 32U * 1024U, 1U * 1024U);
target_add_ram32(target, 0x20000000, 16U * 1024U);
break;
case 0x000cU: // LQFP48
case 0x000dU: // LQFP32
case 0x000eU: // QFN32_5x5
case 0x000fU: // QFN32_4x4
case 0x0010U: // QFN20
case 0x0011U: // TSSOP20
case 0x0014U: // QFN28
// Flash (4): 16 KiB / 1 KiB per block
stm32f1_add_flash(target, 0x08000000, 16U * 1024U, 1U * 1024U);
target_add_ram32(target, 0x20000000, 8U * 1024U);
break;
// Unknown/undocumented
default:
return false;
}

target->driver = "AT32F421";
target->part_id = part_id;
target->target_options |= STM32F1_TOPT_32BIT_WRITES;
target->mass_erase = stm32f1_mass_erase;
// TODO: AT32F421 have 512 bytes of User System Data
return stm32f1_configure_dbgmcu(target, STM32F1_DBGMCU_CONFIG);
}

/* Identify AT32F40x "Mainstream" line devices (Cortex-M4) */
bool at32f40x_probe(target_s *target)
{
Expand All @@ -475,11 +570,23 @@ bool at32f40x_probe(target_s *target)
const uint32_t idcode = target_mem32_read32(target, STM32F1_DBGMCU_IDCODE);
const uint32_t series = idcode & AT32F4x_IDCODE_SERIES_MASK;
const uint16_t part_id = idcode & AT32F4x_IDCODE_PART_MASK;
const uint32_t project_id = target_mem32_read8(target, AT32F4x_PROJECT_ID);

if (series == AT32F40_SERIES)
return at32f40_detect(target, part_id);
if (series == AT32F41_SERIES)
return at32f41_detect(target, part_id);
if (series == AT32F40_SERIES) {
if (project_id == 2U) // F403
return false;
if (project_id == 7U || project_id == 8U) // F403A, F407
return at32f40_detect(target, part_id);
}
if (series == AT32F41_SERIES) {
if (project_id == 4U)
return at32f413_detect(target, part_id);
if (project_id == 5U)
return at32f415_detect(target, part_id);
}
// Value line
if ((series == AT32F421_SERIES || series == AT32F421_SERIES_16KB) && (project_id == 9U))
return at32f421_detect(target, part_id);
return false;
}

Expand Down

0 comments on commit 9cfa5f3

Please sign in to comment.