Skip to content

Commit

Permalink
riscv32: add ch32v3 target probe
Browse files Browse the repository at this point in the history
  • Loading branch information
perigoso authored and rg-silva committed Aug 11, 2023
1 parent 4a1dcca commit b9cad21
Show file tree
Hide file tree
Showing 5 changed files with 129 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ SRC = \
spi.c \
stm32f1.c \
ch32f1.c \
ch32vx.c \
stm32f4.c \
stm32h5.c \
stm32h7.c \
Expand Down
123 changes: 123 additions & 0 deletions src/target/ch32vx.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
/*
* This file is part of the Black Magic Debug project.
*
* Copyright (C) 2022 1BitSquared <[email protected]>
* Written by Rafael Silva <[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/>.
*/

/* This file implements RISC-V CH32Vx target specific functions */

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

/* IDCODE register */
#define CH32VX_IDCODE 0x1ffff704U
#define CH32VX_IDCODE_MASK 0x0ffffff0f
#define CH32VX_IDCODE_FAMILY_OFFSET 20U
#define CH32VX_IDCODE_FAMILY_MASK (0xfffU << CH32VX_IDCODE_FAMILY_OFFSET)

#define CH32V203_IDCODE_FAMILY 0x203U
#define CH32V208_IDCODE_FAMILY 0x208U
#define CH32V305_IDCODE_FAMILY 0x305U
#define CH32V303_IDCODE_FAMILY 0x303U
#define CH32V307_IDCODE_FAMILY 0x307U

/* Electronic Signature (ESIG) registers */
#define CH32VX_ESIG_FLASH_CAP 0x1ffff7e0U /* Flash capacity register, 16 bits, KiB units */
#define CH32VX_ESIG_UID1 0x1ffff7e8U /* Unique ID register, bits 0:31 */
#define CH32VX_ESIG_UID2 0x1ffff7ecU /* Unique ID register, bits 32:63 */
#define CH32VX_ESIG_UID3 0x1ffff7f0U /* Unique ID register, bits 64:95 */

static bool ch32vx_uid_cmd(target_s *t, int argc, const char **argv);

const command_s ch32vx_cmd_list[] = {
{"uid", ch32vx_uid_cmd, "Prints 96 bit unique id"},
{NULL, NULL, NULL},
};

static uint32_t ch32vx_read_flash_size(target_s *const t)
{
return target_mem_read16(t, CH32VX_ESIG_FLASH_CAP) * 1024U;
}

static void ch32vx_read_uid(target_s *const t, uint8_t *const uid)
{
for (size_t uid_reg_offset = 0; uid_reg_offset < 12U; uid_reg_offset += 4U)
write_be4(uid, uid_reg_offset, target_mem_read32(t, CH32VX_ESIG_UID1 + uid_reg_offset));
}

bool ch32vx_probe(target_s *const target)
{
const uint32_t idcode = target_mem_read32(target, CH32VX_IDCODE);

switch (idcode & CH32VX_IDCODE_MASK) {
case 0x30330504U: /* CH32V303CBT6 */
case 0x30320504U: /* CH32V303RBT6 */
case 0x30310504U: /* CH32V303RCT6 */
case 0x30300504U: /* CH32V303VCT6 */
case 0x30520508U: /* CH32V305FBP6 */
case 0x30500508U: /* CH32V305RBT6 */
case 0x30730508U: /* CH32V307WCU6 */
case 0x30720508U: /* CH32V307FBP6 */
case 0x30710508U: /* CH32V307RCT6 */
case 0x30700508U: /* CH32V307VCT6 */
break;
default:
return false;
break;
}

const uint16_t family = (idcode & CH32VX_IDCODE_FAMILY_MASK) >> CH32VX_IDCODE_FAMILY_OFFSET;
switch (family) {
case CH32V303_IDCODE_FAMILY:
target->driver = "CH32V303";
break;
case CH32V305_IDCODE_FAMILY:
target->driver = "CH32V305";
break;
case CH32V307_IDCODE_FAMILY:
target->driver = "CH32V307";
break;
default:
return false;
break;
}

DEBUG_WARN("CH32Vx flash size: %u\n", ch32vx_read_flash_size(target));

target->part_id = idcode;

return true;
}

/* Reads the 96 bit unique id */
static bool ch32vx_uid_cmd(target_s *const target, const int argc, const char **const argv)
{
(void)argc;
(void)argv;

uint8_t uid[12U];
ch32vx_read_uid(target, uid);

tc_printf(target, "Unique id: 0x");
for (size_t i = 0U; i < sizeof(uid); i++)
tc_printf(target, "%02" PRIx8, uid[i]);
tc_printf(target, "\n");

return true;
}
3 changes: 3 additions & 0 deletions src/target/riscv32.c
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,9 @@ bool riscv32_probe(target_s *const target)
case JEP106_MANUFACTURER_ESPRESSIF:
PROBE(esp32c3_probe);
break;
case NOT_JEP106_MANUFACTURER_WCH:
PROBE(ch32vx_probe);
break;
}
#if PC_HOSTED == 0
gdb_outf("Please report unknown device with Designer 0x%x\n", target->designer_code);
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 @@ -84,6 +84,7 @@ CORTEXM_PROBE_WEAK_NOP(efm32_aap_probe)
CORTEXM_PROBE_WEAK_NOP(rp_rescue_probe)
CORTEXM_PROBE_WEAK_NOP(lpc55_dmap_probe)

TARGET_PROBE_WEAK_NOP(ch32vx_probe)
TARGET_PROBE_WEAK_NOP(ch32f1_probe)
TARGET_PROBE_WEAK_NOP(gd32f1_probe)
TARGET_PROBE_WEAK_NOP(gd32vf1_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 @@ -41,6 +41,7 @@ bool efm32_aap_probe(adiv5_access_port_s *ap);
bool rp_rescue_probe(adiv5_access_port_s *ap);
bool lpc55_dmap_probe(adiv5_access_port_s *ap);

bool ch32vx_probe(target_s *target);
bool ch32f1_probe(target_s *target); // will catch all the clones
bool at32fxx_probe(target_s *target); // STM32 clones from Artery
bool mm32l0xx_probe(target_s *target);
Expand Down

0 comments on commit b9cad21

Please sign in to comment.