mirror of
https://git.code.sf.net/p/openocd/code
synced 2025-04-03 22:45:27 +00:00
Add basic support for Texas Instruments MSPM0L, C and G family of Cortex-M0 based micro-controllers. Change-Id: If2b5b1eca001f74d501ede67ec621c7497548a85 Co-developed-by: Henry Nguyen <h-nguyen8@ti.com> Signed-off-by: Henry Nguyen <h-nguyen8@ti.com> Signed-off-by: Nishanth Menon <nm@ti.com> Reviewed-on: https://review.openocd.org/c/openocd/+/8385 Tested-by: jenkins Reviewed-by: Antonio Borneo <borneo.antonio@gmail.com> Reviewed-by: zapb <dev@zapb.de>
200 lines
5.6 KiB
INI
200 lines
5.6 KiB
INI
# SPDX-License-Identifier: GPL-2.0-or-later
|
|
# Copyright (C) 2023-2025 Texas Instruments Incorporated - https://www.ti.com/
|
|
#
|
|
# Texas Instruments MSPM0L/G - ARM Cortex-M0 @ 32MHz
|
|
# https://www.ti.com/microcontrollers-mcus-processors/arm-based-microcontrollers/arm-cortex-m0-mcus/overview.html
|
|
#
|
|
|
|
source [find bitsbytes.tcl]
|
|
|
|
if { [info exists CHIPNAME] } {
|
|
set _CHIPNAME $CHIPNAME
|
|
} else {
|
|
# Meant to work with MSPM0L and MSPM0G class of devices.
|
|
set _CHIPNAME mspm0x
|
|
}
|
|
|
|
if { [info exists CPUTAPID] } {
|
|
set _DAP_TAPID $CPUTAPID
|
|
} else {
|
|
set _DAP_TAPID 0x4ba00477
|
|
}
|
|
|
|
if { [info exists DAP_SWD_ID] } {
|
|
set _DAP_SWD_ID $DAP_SWD_ID
|
|
} else {
|
|
set _DAP_SWD_ID 0x2ba01477
|
|
}
|
|
|
|
source [find target/swj-dp.tcl]
|
|
|
|
# MSPM0 only supports swd, so set it here and save a line for custom boards
|
|
transport select swd
|
|
|
|
set _DAP_ID $_DAP_SWD_ID
|
|
|
|
swj_newdap $_CHIPNAME cpu -irlen 4 -expected-id $_DAP_ID
|
|
dap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu
|
|
|
|
set _TARGETNAME $_CHIPNAME.cpu
|
|
target create $_TARGETNAME cortex_m -dap $_CHIPNAME.dap
|
|
|
|
if { [info exists WORKAREABASE] } {
|
|
set _WORKAREABASE $WORKAREABASE
|
|
} else {
|
|
set _WORKAREABASE 0x20000000
|
|
}
|
|
if { [info exists WORKAREASIZE] } {
|
|
set _WORKAREASIZE $WORKAREASIZE
|
|
} else {
|
|
# Smallest SRAM size is 1K SRAM.
|
|
set _WORKAREASIZE 0x400
|
|
}
|
|
|
|
#
|
|
# MSPM0 Debug SubSystem Mailbox (DSSM) Communication helpers
|
|
#
|
|
|
|
proc _mspm0_wait_for_dssm_response {command} {
|
|
# Wait for SECAP::RCR rx_valid to be set
|
|
set timeout 1000
|
|
while { [expr { [$::_CHIPNAME.dap apreg 2 0xc] & 0x1}] != 0x1 } {
|
|
sleep 1
|
|
set timeout [expr {$timeout - 1}]
|
|
if { $timeout == 0 } {
|
|
set rcr [$::_CHIPNAME.dap apreg 2 0xc]
|
|
return -code error [format "MSPM0 SECAP RCR=0x%08x timeout rx_valid" $rcr]
|
|
}
|
|
}
|
|
|
|
# Read SECAP::RXD to clear the RX_VALID bit
|
|
set rxd [$::_CHIPNAME.dap apreg 2 0x8]
|
|
# Read SECAP::RCR
|
|
set rcr [$::_CHIPNAME.dap apreg 2 0xc]
|
|
|
|
# Check if we got successful response. This is denoted as:
|
|
# 8 LSBits of $command should matchup with SECAP::RCR
|
|
# and
|
|
# SECAP::RXD should be 0x10003
|
|
if { ([expr { $command & 0xff}] == $rcr) && ($rxd == 0x10003) } {
|
|
return 0
|
|
}
|
|
|
|
# Provide some debug log for users to report back if CMD fails.
|
|
return -code error [format "MSPM0 SECAP CMD FAIL! RXD: 0x%08X RCR: 0x%08X" $rxd $rcr]
|
|
}
|
|
|
|
proc _mspm0_dssm_command {command} {
|
|
# SECAP::TCR = command
|
|
$::_CHIPNAME.dap apreg 2 0x4 $command
|
|
# SECAP::TDR = 0x0
|
|
$::_CHIPNAME.dap apreg 2 0x0 0x0
|
|
# Read SECAP::RCR and RXD to clear up any prev pending reads
|
|
set rxd [$::_CHIPNAME.dap apreg 2 0x8]
|
|
set rcr [$::_CHIPNAME.dap apreg 2 0xc]
|
|
# Make sure everything is synced
|
|
sleep 1000
|
|
# Trigger nRST
|
|
mspm0_board_reset
|
|
|
|
# Wait for ROM to do it's magic and respond back
|
|
set res [_mspm0_wait_for_dssm_response $command]
|
|
if { $res } {
|
|
return $res
|
|
}
|
|
# Paranoid.. make sure ROM does what it is meant to do
|
|
# RX valid should have been cleared after the operation is
|
|
# complete
|
|
sleep 1000
|
|
|
|
# Trigger nRST to get back to sane system
|
|
mspm0_board_reset
|
|
sleep 1000
|
|
|
|
return 0
|
|
}
|
|
|
|
# NOTE: Password authentication scheme is NOT supported atm.
|
|
# mspm0_factory_reset: Factory reset the board
|
|
proc mspm0_factory_reset {} {
|
|
set res [_mspm0_dssm_command 0x020a]
|
|
if { $res } {
|
|
echo "Factory Reset failed!"
|
|
} else {
|
|
echo "Factory reset success! Halting processor"
|
|
# We need to halt the processor else the WDT fires!
|
|
halt
|
|
}
|
|
return $res
|
|
}
|
|
|
|
add_help_text mspm0_factory_reset "Force Factory reset to recover 'bricked' board"
|
|
|
|
# NOTE: Password authentication scheme is NOT supported atm.
|
|
# mspm0_mass_erase: Mass erase flash
|
|
proc mspm0_mass_erase {} {
|
|
set res [_mspm0_dssm_command 0x020c]
|
|
if { $res } {
|
|
echo "Mass Erase failed!"
|
|
} else {
|
|
echo "Mass Erase success! Halting Processor"
|
|
# We need to halt the processor else the WDT fires!
|
|
halt
|
|
}
|
|
return $res
|
|
}
|
|
|
|
add_help_text mspm0_mass_erase "Mass erase flash"
|
|
|
|
# mspm0_start_bootloader: Ask explicitly for bootloader startup
|
|
proc mspm0_start_bootloader {} {
|
|
set res [_mspm0_dssm_command 0x0108]
|
|
if { $res } {
|
|
echo "Start BL failed!"
|
|
}
|
|
return $res
|
|
}
|
|
|
|
add_help_text mspm0_start_bootloader "Ask explicitly for bootloader startup"
|
|
|
|
# MSPM0 requires board level NRST reset to be toggled for
|
|
# Factory reset operations to function.
|
|
# However this cannot be the default configuration as this
|
|
# prevents reset init reset halt to function properly
|
|
# since the Debug Subsystem (debugss) logic or coresight
|
|
# seems impacted by nRST.
|
|
# This can be overridden in board file as required.
|
|
#
|
|
# mspm0_board_reset: Board level reset
|
|
proc mspm0_board_reset {} {
|
|
set user_reset_config [reset_config]
|
|
reset_config srst_only
|
|
set errno [catch {reset}]
|
|
eval reset_config $user_reset_config
|
|
if {$errno} {error}
|
|
}
|
|
|
|
add_help_text mspm0_board_reset "Request a board level reset"
|
|
|
|
# If the flash is empty or the device is already in low-power state, then
|
|
# debug access is not available. to handle this, explicitly control power ap
|
|
# to provide access. Refer to Technical Reference Manual for further info.
|
|
proc _mspm0_enable_low_power_mode { } {
|
|
# PWR_AP::DPREC <= FRCACT(3)=1, RST_CTL(14:16)=1, IHIB_SLP(20)=1
|
|
$::_CHIPNAME.dap apreg 4 0x00 0x104008
|
|
# PWR_AP::SPREC <= SYSRST=1
|
|
$::_CHIPNAME.dap apreg 4 0xF0 0x01
|
|
# PWR_AP::DPREC <= FRCACT(3)=1, IHIB_SLP(20)=1
|
|
$::_CHIPNAME.dap apreg 4 0x00 0x100008
|
|
}
|
|
|
|
$_TARGETNAME configure -event examine-start { _mspm0_enable_low_power_mode }
|
|
$_TARGETNAME configure -work-area-phys $_WORKAREABASE -work-area-size $_WORKAREASIZE -work-area-backup 0
|
|
|
|
set _FLASHNAME $_CHIPNAME.flash
|
|
flash bank $_FLASHNAME.main mspm0 0 0 0 0 $_TARGETNAME
|
|
flash bank $_FLASHNAME.nonmain mspm0 0x41c00000 0 0 0 $_TARGETNAME
|
|
flash bank $_FLASHNAME.data mspm0 0x41d00000 0 0 0 $_TARGETNAME
|
|
|
|
cortex_m reset_config sysresetreq
|