Merge remote-tracking branch 'origin/riscv' into riscv-compliance-rebase

This commit is contained in:
Megan Wachs 2018-08-29 15:45:11 -07:00
commit 34ee883aef
189 changed files with 22856 additions and 1704 deletions

4
README
View File

@ -125,8 +125,8 @@ Flash drivers
ADUC702x, AT91SAM, ATH79, AVR, CFI, DSP5680xx, EFM32, EM357, FM3, FM4, Kinetis,
LPC8xx/LPC1xxx/LPC2xxx/LPC541xx, LPC2900, LPCSPIFI, Marvell QSPI,
Milandr, NIIET, NuMicro, PIC32mx, PSoC4, SiM3x, Stellaris, STM32, STMSMI,
STR7x, STR9x, nRF51; NAND controllers of AT91SAM9, LPC3180, LPC32xx,
Milandr, NIIET, NuMicro, PIC32mx, PSoC4, PSoC5LP, SiM3x, Stellaris, STM32,
STMSMI, STR7x, STR9x, nRF51; NAND controllers of AT91SAM9, LPC3180, LPC32xx,
i.MX31, MXC, NUC910, Orion/Kirkwood, S3C24xx, S3C6400, XMC1xxx, XMC4xxx.

View File

@ -115,7 +115,8 @@ m4_define([USB1_ADAPTERS],
[[ulink], [Keil ULINK JTAG Programmer], [ULINK]],
[[usb_blaster_2], [Altera USB-Blaster II Compatible], [USB_BLASTER_2]],
[[ft232r], [Bitbang mode of FT232R based devices], [FT232R]],
[[vsllink], [Versaloon-Link JTAG Programmer], [VSLLINK]]])
[[vsllink], [Versaloon-Link JTAG Programmer], [VSLLINK]],
[[xds110], [TI XDS110 Debug Probe], [XDS110]]])
m4_define([USB_ADAPTERS],
[[[osbdm], [OSBDM (JTAG only) Programmer], [OSBDM]],
@ -659,7 +660,7 @@ PROCESS_ADAPTERS([USB0_ADAPTERS], ["x$use_libusb0" = "xyes"], [libusb-0.1])
PROCESS_ADAPTERS([HIDAPI_ADAPTERS], ["x$use_hidapi" = "xyes"], [hidapi])
PROCESS_ADAPTERS([HIDAPI_USB1_ADAPTERS], ["x$use_hidapi" = "xyes" -a "x$use_libusb1" = "xyes"], [hidapi and libusb-1.x])
PROCESS_ADAPTERS([LIBFTDI_ADAPTERS], ["x$use_libftdi" = "xyes"], [libftdi])
PROCESS_ADAPTERS([LIBJAYLINK_ADAPTERS], ["x$use_internal_libjaylink" = "xyes" -o "x$use_libjaylink" = "xyes"], [libjaylink-0.1])
PROCESS_ADAPTERS([LIBJAYLINK_ADAPTERS], ["x$use_internal_libjaylink" = "xyes" -o "x$use_libjaylink" = "xyes"], [libjaylink-0.2])
AS_IF([test "x$build_openjtag" = "xyes"], [
AS_IF([test "x$use_libusb1" != "xyes" -a "x$use_libusb0" != "xyes"], [

View File

@ -128,6 +128,12 @@ ATTRS{idVendor}=="1781", ATTRS{idProduct}=="0c63", MODE="660", GROUP="plugdev",
# TI/Luminary Stellaris In-Circuit Debug Interface (ICDI) Board
ATTRS{idVendor}=="1cbe", ATTRS{idProduct}=="00fd", MODE="660", GROUP="plugdev", TAG+="uaccess"
# TI XDS110 Debug Probe (Launchpads and Standalone)
ATTRS{idVendor}=="0451", ATTRS{idProduct}=="bef3", MODE="660", GROUP="plugdev", TAG+="uaccess"
# TI Tiva-based ICDI and XDS110 probes in DFU mode
ATTRS{idVendor}=="1cbe", ATTRS{idProduct}=="00ff", MODE="660", GROUP="plugdev", TAG+="uaccess"
# Ambiq Micro EVK and Debug boards.
ATTRS{idVendor}=="2aec", ATTRS{idProduct}=="6010", MODE="664", GROUP="plugdev", TAG+="uaccess"
ATTRS{idVendor}=="2aec", ATTRS{idProduct}=="6011", MODE="664", GROUP="plugdev", TAG+="uaccess"

View File

@ -17,9 +17,7 @@
* 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, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#include "dcc_stdio.h"

View File

@ -15,9 +15,7 @@
* 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, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef DCC_STDIO_H

View File

@ -15,9 +15,7 @@
* 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, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#include "dcc_stdio.h"

View File

@ -13,9 +13,7 @@
* 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, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#include "dcc.h"

View File

@ -13,9 +13,7 @@
* 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, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef dccH
#define dccH

View File

@ -13,9 +13,7 @@
* 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, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#include "platform.h"

View File

@ -13,9 +13,7 @@
* 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, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OCL_H
#define OCL_H

View File

@ -13,9 +13,7 @@
* 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, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef platformH
#define platformH

View File

@ -13,9 +13,7 @@
* 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, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#include "samflash.h"

View File

@ -13,9 +13,7 @@
* 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, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef samflashH
#define samflashH

View File

@ -0,0 +1,83 @@
BIN2C = ../../../../src/helper/bin2char.sh
CROSS_COMPILE ?= arm-none-eabi-
GCC = $(CROSS_COMPILE)gcc
OBJCOPY = $(CROSS_COMPILE)objcopy
FLAGS = -mthumb -Os -ffunction-sections -fdata-sections -g -gdwarf-3
FLAGS += -gstrict-dwarf -Wall -fno-strict-aliasing --asm
CFLAGS = -c -I.
CC26X0_CFLAGS = -mcpu=cortex-m3 -DDEVICE_CC26X0
CC26X2_CFLAGS = -mcpu=cortex-m4 -DDEVICE_CC26X2
CC26X0_OBJS := \
cc26x0/flashloader.o \
cc26x0/main.o \
cc26x0/startup.o \
cc26x0/flash.o
CC26X2_OBJS := \
cc26x2/flashloader.o \
cc26x2/main.o \
cc26x2/startup.o \
cc26x2/flash.o
all: cc26x0_algo.inc cc26x2_algo.inc
cc26x0/%.o: %.c
@echo 'Building file: $<'
@echo 'Invoking: GNU Compiler'
$(GCC) $(FLAGS) $(CFLAGS) $(CC26X0_CFLAGS) -o"$@" "$(shell echo $<)"
@echo 'Finished building: $<'
@echo ' '
cc26x2/%.o: %.c
@echo 'Building file: $<'
@echo 'Invoking: GNU Compiler'
$(GCC) $(FLAGS) $(CFLAGS) $(CC26X2_CFLAGS) -o"$@" "$(shell echo $<)"
@echo 'Finished building: $<'
@echo ' '
cc26x0_algo.out: $(CC26X0_OBJS)
@echo 'Building target: $@'
@echo 'Invoking: GNU Linker'
$(GCC) $(FLAGS) -o$@ $(CC26X0_OBJS) -Wl,-T"cc26x0/cc26x0r2f.lds"
@echo 'Finished building target: $@'
@echo ' '
cc26x2_algo.out: $(CC26X2_OBJS)
@echo 'Building target: $@'
@echo 'Invoking: GNU Linker'
$(GCC) $(FLAGS) -o$@ $(CC26X2_OBJS) -Wl,-T"cc26x2/cc26x2r1f.lds"
@echo 'Finished building target: $@'
@echo ' '
%.bin: %.out
@echo 'Building target: $@'
@echo 'Invoking: GNU Objcopy Utility'
$(OBJCOPY) -Obinary $< $@
@echo 'Finished building target: $@'
@echo ' '
%.inc: %.bin
@echo 'Building target: $@'
@echo 'Invoking Bin2Char Script'
$(BIN2C) < $< > $@
rm $< $*.out
@echo 'Finished building target: $@'
@echo ' '
clean:
@echo 'Cleaning Targets and Build Artifacts'
rm -rf *.inc *.bin *.out *.map
rm -rf cc26x0/*.o cc26x0/*.d
rm -rf cc26x2/*.o cc26x2/*.d
@echo 'Finished clean'
@echo ' '
.PRECIOUS: %.bin
.PHONY: all clean

View File

@ -0,0 +1,90 @@
/******************************************************************************
*
* Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com/
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* distribution.
*
* Neither the name of Texas Instruments Incorporated nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************/
/* Entry Point */
ENTRY( entry )
/* System memory map */
MEMORY
{
/* Application is stored in and executes from SRAM */
PROGRAM (RWX) : ORIGIN = 0x20000000, LENGTH = 0x1BD8
BUFFERS (RWX) : ORIGIN = 0x20001BD8, LENGTH = 0x3028
}
/* Section allocation in memory */
SECTIONS
{
.text :
{
_text = .;
*(.entry*)
*(.text*)
_etext = .;
} > PROGRAM
.data :
{ _data = .;
*(.rodata*)
*(.data*)
_edata = .;
}
.bss :
{
__bss_start__ = .;
_bss = .;
*(.bss*)
*(COMMON)
_ebss = .;
__bss_end__ = .;
} > PROGRAM
.stack :
{
_stack = .;
*(.stack*)
_estack = .;
} > PROGRAM
.buffers :
{
_buffers = .;
*(.buffers.g_cfg)
*(.buffers.g_buf1)
*(.buffers.g_buf2)
*(.buffers*)
_ebuffers = .;
} > BUFFERS
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,90 @@
/******************************************************************************
*
* Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com/
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* distribution.
*
* Neither the name of Texas Instruments Incorporated nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************/
/* Entry Point */
ENTRY( entry )
/* System memory map */
MEMORY
{
/* Application is stored in and executes from SRAM */
PROGRAM (RWX) : ORIGIN = 0x20000000, LENGTH = 0x1FD8
BUFFERS (RWX) : ORIGIN = 0x20001FD8, LENGTH = 0x6028
}
/* Section allocation in memory */
SECTIONS
{
.text :
{
_text = .;
*(.entry*)
*(.text*)
_etext = .;
} > PROGRAM
.data :
{ _data = .;
*(.rodata*)
*(.data*)
_edata = .;
}
.bss :
{
__bss_start__ = .;
_bss = .;
*(.bss*)
*(COMMON)
_ebss = .;
__bss_end__ = .;
} > PROGRAM
.stack :
{
_stack = .;
*(.stack*)
_estack = .;
} > PROGRAM
.buffers :
{
_buffers = .;
*(.buffers.g_cfg)
*(.buffers.g_buf1)
*(.buffers.g_buf2)
*(.buffers*)
_ebuffers = .;
} > BUFFERS
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,977 @@
/******************************************************************************
*
* Copyright (C) 2016-2018 Texas Instruments Incorporated - http://www.ti.com/
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* distribution.
*
* Neither the name of Texas Instruments Incorporated nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************/
#include <stdint.h>
#include <stdbool.h>
#include "flash.h"
/******************************************************************************
*
* Defines for accesses to the security control in the customer configuration
* area in flash top sector.
*
******************************************************************************/
#define CCFG_OFFSET_SECURITY CCFG_O_BL_CONFIG
#define CCFG_SIZE_SECURITY 0x00000014
/******************************************************************************
*
* Default values for security control in customer configuration area in flash
* top sector.
*
******************************************************************************/
const uint8_t g_ccfg_default_sec[] = {
0xFF, 0xFF, 0xFF, 0xC5,
0xFF, 0xFF, 0xFF, 0xFF,
0xC5, 0xFF, 0xFF, 0xFF,
0xC5, 0xC5, 0xC5, 0xFF,
0xC5, 0xC5, 0xC5, 0xFF
};
typedef uint32_t (*flash_prg_pntr_t) (uint8_t *, uint32_t, uint32_t);
typedef uint32_t (*flash_sector_erase_pntr_t) (uint32_t);
/******************************************************************************
*
* Function prototypes for static functions
*
******************************************************************************/
static void issue_fsm_command(flash_state_command_t command);
static void enable_sectors_for_write(void);
static uint32_t scale_cycle_values(uint32_t specified_timing,
uint32_t scale_value);
static void set_write_mode(void);
static void trim_for_write(void);
static void set_read_mode(void);
/******************************************************************************
*
* Erase a flash sector
*
******************************************************************************/
uint32_t flash_sector_erase(uint32_t sector_address)
{
uint32_t error_return;
flash_sector_erase_pntr_t func_pntr;
/* Call ROM function */
func_pntr = (uint32_t (*)(uint32_t))(ROM_API_FLASH_TABLE[5]);
error_return = func_pntr(sector_address);
/* Enable standby because ROM function might have disabled it */
HWREGBITW(FLASH_BASE + FLASH_O_CFG, FLASH_CFG_DIS_STANDBY_BITN) = 0;
/* Return status of operation. */
return error_return;
}
/******************************************************************************
*
* Erase all unprotected sectors in the flash main bank
*
******************************************************************************/
uint32_t flash_bank_erase(bool force_precondition)
{
uint32_t error_return;
uint32_t sector_address;
uint32_t reg_val;
/* Enable all sectors for erase. */
enable_sectors_for_write();
/* Clear the Status register. */
issue_fsm_command(FAPI_CLEAR_STATUS);
/* Enable erase of all sectors and enable precondition if required. */
reg_val = HWREG(FLASH_BASE + FLASH_O_FSM_ST_MACHINE);
HWREG(FLASH_BASE + FLASH_O_FSM_WR_ENA) = FSM_REG_WRT_ENABLE;
HWREG(FLASH_BASE + FLASH_O_FSM_SECTOR1) = 0x00000000;
HWREG(FLASH_BASE + FLASH_O_FSM_SECTOR2) = 0x00000000;
if (force_precondition)
HWREG(FLASH_BASE + FLASH_O_FSM_ST_MACHINE) |=
FLASH_FSM_ST_MACHINE_DO_PRECOND;
HWREG(FLASH_BASE + FLASH_O_FSM_WR_ENA) = FSM_REG_WRT_DISABLE;
/* Issue the bank erase command to the FSM. */
issue_fsm_command(FAPI_ERASE_BANK);
/* Wait for erase to finish. */
while (flash_check_fsm_for_ready() == FAPI_STATUS_FSM_BUSY)
;
/* Update status. */
error_return = flash_check_fsm_for_error();
/* Disable sectors for erase. */
flash_disable_sectors_for_write();
/* Set configured precondition mode since it may have been forced on. */
if (!(reg_val & FLASH_FSM_ST_MACHINE_DO_PRECOND)) {
HWREG(FLASH_BASE + FLASH_O_FSM_WR_ENA) = FSM_REG_WRT_ENABLE;
HWREG(FLASH_BASE + FLASH_O_FSM_ST_MACHINE) &=
~FLASH_FSM_ST_MACHINE_DO_PRECOND;
HWREG(FLASH_BASE + FLASH_O_FSM_WR_ENA) = FSM_REG_WRT_DISABLE;
}
/* Program security data to default values in the customer configuration */
/* area within the flash top sector if erase was successful. */
if (error_return == FAPI_STATUS_SUCCESS) {
sector_address = FLASHMEM_BASE + flash_size_get() -
flash_sector_size_get();
error_return = flash_program((uint8_t *)g_ccfg_default_sec,
(sector_address + CCFG_OFFSET_SECURITY),
CCFG_SIZE_SECURITY);
}
/* Return status of operation. */
return error_return;
}
/******************************************************************************
*
* Programs unprotected main bank flash sectors
*
******************************************************************************/
uint32_t flash_program(uint8_t *data_buffer, uint32_t address, uint32_t count)
{
uint32_t error_return;
flash_prg_pntr_t func_pntr;
/* Call ROM function */
func_pntr = (uint32_t (*)(uint8_t *, uint32_t, uint32_t))
(ROM_API_FLASH_TABLE[6]);
error_return = func_pntr(data_buffer, address, count);
/* Enable standby because ROM function might have disabled it */
HWREGBITW(FLASH_BASE + FLASH_O_CFG, FLASH_CFG_DIS_STANDBY_BITN) = 0;
/* Return status of operation. */
return error_return;
}
/******************************************************************************
*
* Disables all sectors for erase and programming on the active bank
*
******************************************************************************/
void flash_disable_sectors_for_write(void)
{
/* Configure flash back to read mode */
set_read_mode();
/* Disable Level 1 Protection. */
HWREG(FLASH_BASE + FLASH_O_FBPROT) = FLASH_FBPROT_PROTL1DIS;
/* Disable all sectors for erase and programming. */
HWREG(FLASH_BASE + FLASH_O_FBSE) = 0x0000;
/* Enable Level 1 Protection. */
HWREG(FLASH_BASE + FLASH_O_FBPROT) = 0;
/* Protect sectors from sector erase. */
HWREG(FLASH_BASE + FLASH_O_FSM_WR_ENA) = FSM_REG_WRT_ENABLE;
HWREG(FLASH_BASE + FLASH_O_FSM_SECTOR1) = 0xFFFFFFFF;
HWREG(FLASH_BASE + FLASH_O_FSM_SECTOR2) = 0xFFFFFFFF;
HWREG(FLASH_BASE + FLASH_O_FSM_WR_ENA) = FSM_REG_WRT_DISABLE;
}
/******************************************************************************
*
* Issues a command to the Flash State Machine.
*
******************************************************************************/
static void issue_fsm_command(flash_state_command_t command)
{
/* Enable write to FSM register. */
HWREG(FLASH_BASE + FLASH_O_FSM_WR_ENA) = FSM_REG_WRT_ENABLE;
/* Issue FSM command. */
HWREG(FLASH_BASE + FLASH_O_FSM_CMD) = command;
/* Start command execute. */
HWREG(FLASH_BASE + FLASH_O_FSM_EXECUTE) = FLASH_CMD_EXEC;
/* Disable write to FSM register. */
HWREG(FLASH_BASE + FLASH_O_FSM_WR_ENA) = FSM_REG_WRT_DISABLE;
}
/******************************************************************************
*
* Enables all sectors for erase and programming on the active bank.
*
* This function disables the idle reading power reduction mode, selects the
* flash bank and enables all sectors for erase and programming on the active
* bank.
* Sectors may be protected from programming depending on the value of the
* FLASH_O_FSM_BSLPx registers.
* Sectors may be protected from erase depending on the value of the
* FLASH_O_FSM_BSLEx registers. Additional sector erase protection is set by
* the FLASH_O_FSM_SECTOR1 register.
*
******************************************************************************/
static void enable_sectors_for_write(void)
{
/* Trim flash module for program/erase operation. */
trim_for_write();
/* Configure flash to write mode */
set_write_mode();
/* Select flash bank. */
HWREG(FLASH_BASE + FLASH_O_FMAC) = 0x00;
/* Disable Level 1 Protection. */
HWREG(FLASH_BASE + FLASH_O_FBPROT) = FLASH_FBPROT_PROTL1DIS;
/* Enable all sectors for erase and programming. */
HWREG(FLASH_BASE + FLASH_O_FBSE) = 0xFFFF;
/* Enable Level 1 Protection */
HWREG(FLASH_BASE + FLASH_O_FBPROT) = 0;
}
/******************************************************************************
*
* Trims the Flash Bank and Flash Pump for program/erase functionality
*
* This trimming will make it possible to perform erase and program operations
* of the flash. Trim values are loaded from factory configuration area
* (referred to as FCGF1). The trimming done by this function is valid until
* reset of the flash module.
*
* Some registers shall be written with a value that is a number of FCLK
* cycles. The trim values controlling these registers have a value of
* number of half us. FCLK = SysClk / ((RWAIT+1) x 2).
*
******************************************************************************/
static void trim_for_write(void)
{
uint32_t value;
uint32_t temp_val;
uint32_t fclk_scale;
uint32_t rwait;
/* Return if flash is already trimmed for program/erase operations. */
if (HWREG(FLASH_BASE + FLASH_O_FWFLAG) & FW_WRT_TRIMMED)
return;
/* Configure the FSM registers */
/* Enable access to the FSM registers. */
HWREG(FLASH_BASE + FLASH_O_FSM_WR_ENA) = FSM_REG_WRT_ENABLE;
/* Determine the scaling value to be used on timing related trim values. */
/* The value is based on the flash module clock frequency and RWAIT */
rwait = (HWREG(FLASH_BASE + FLASH_O_FRDCTL) &
FLASH_FRDCTL_RWAIT_M) >> FLASH_FRDCTL_RWAIT_S;
fclk_scale = (16 * FLASH_MODULE_CLK_FREQ) / (rwait + 1);
/* Configure Program pulse width bits 15:0. */
/* (FCFG1 offset 0x188 bits 15:0). */
value = (HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_PROG_EP) &
FCFG1_FLASH_PROG_EP_PROGRAM_PW_M) >>
FCFG1_FLASH_PROG_EP_PROGRAM_PW_S;
value = scale_cycle_values(value, fclk_scale);
HWREG(FLASH_BASE + FLASH_O_FSM_PRG_PW) =
(HWREG(FLASH_BASE + FLASH_O_FSM_PRG_PW) &
~FLASH_FSM_PRG_PW_PROG_PUL_WIDTH_M) |
((value << FLASH_FSM_PRG_PW_PROG_PUL_WIDTH_S) &
FLASH_FSM_PRG_PW_PROG_PUL_WIDTH_M);
/* Configure Erase pulse width bits 31:0. */
/* (FCFG1 offset 0x18C bits 31:0). */
value = (HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_ERA_PW) &
FCFG1_FLASH_ERA_PW_ERASE_PW_M) >>
FCFG1_FLASH_ERA_PW_ERASE_PW_S;
value = scale_cycle_values(value, fclk_scale);
HWREG(FLASH_BASE + FLASH_O_FSM_ERA_PW) =
(HWREG(FLASH_BASE + FLASH_O_FSM_ERA_PW) &
~FLASH_FSM_ERA_PW_FSM_ERA_PW_M) |
((value << FLASH_FSM_ERA_PW_FSM_ERA_PW_S) &
FLASH_FSM_ERA_PW_FSM_ERA_PW_M);
/* Configure no of flash clock cycles from EXECUTEZ going low to the the
verify data can be read in the program verify mode bits 7:0. */
/* (FCFG1 offset 0x174 bits 23:16). */
value = (HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_C_E_P_R) &
FCFG1_FLASH_C_E_P_R_PV_ACCESS_M) >>
FCFG1_FLASH_C_E_P_R_PV_ACCESS_S;
value = scale_cycle_values(value, fclk_scale);
HWREG(FLASH_BASE + FLASH_O_FSM_EX_VAL) =
(HWREG(FLASH_BASE + FLASH_O_FSM_EX_VAL) &
~FLASH_FSM_EX_VAL_EXE_VALD_M) |
((value << FLASH_FSM_EX_VAL_EXE_VALD_S) &
FLASH_FSM_EX_VAL_EXE_VALD_M);
/* Configure the number of flash clocks from the start of the Read mode at
the end of the operations until the FSM clears the BUSY bit in FMSTAT. */
/* (FCFG1 offset 0x178 bits 23:16). */
value = (HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_P_R_PV) &
FCFG1_FLASH_P_R_PV_RH_M) >>
FCFG1_FLASH_P_R_PV_RH_S;
HWREG(FLASH_BASE + FLASH_O_FSM_RD_H) =
(HWREG(FLASH_BASE + FLASH_O_FSM_RD_H) &
~FLASH_FSM_RD_H_RD_H_M) |
((value << FLASH_FSM_RD_H_RD_H_S) &
FLASH_FSM_RD_H_RD_H_M);
/* Configure Program hold time */
/* (FCFG1 offset 0x178 bits 31:24). */
value = (HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_P_R_PV) &
FCFG1_FLASH_P_R_PV_PH_M) >>
FCFG1_FLASH_P_R_PV_PH_S;
value = scale_cycle_values(value, fclk_scale);
HWREG(FLASH_BASE + FLASH_O_FSM_P_OH) =
(HWREG(FLASH_BASE + FLASH_O_FSM_P_OH) &
~FLASH_FSM_P_OH_PGM_OH_M) |
((value << FLASH_FSM_P_OH_PGM_OH_S) &
FLASH_FSM_P_OH_PGM_OH_M);
/* Configure Erase hold time */
/* (FCFG1 offset 0x17C bits 31:24). */
value = (HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_EH_SEQ) &
FCFG1_FLASH_EH_SEQ_EH_M) >>
FCFG1_FLASH_EH_SEQ_EH_S;
value = scale_cycle_values(value, fclk_scale);
HWREG(FLASH_BASE + FLASH_O_FSM_ERA_OH) =
(HWREG(FLASH_BASE + FLASH_O_FSM_ERA_OH) &
~FLASH_FSM_ERA_OH_ERA_OH_M) |
((value << FLASH_FSM_ERA_OH_ERA_OH_S) &
FLASH_FSM_ERA_OH_ERA_OH_M);
/* Configure Program verify row switch time */
/* (FCFG1 offset0x178 bits 15:8). */
value = (HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_P_R_PV) &
FCFG1_FLASH_P_R_PV_PVH_M) >>
FCFG1_FLASH_P_R_PV_PVH_S;
value = scale_cycle_values(value, fclk_scale);
HWREG(FLASH_BASE + FLASH_O_FSM_PE_VH) =
(HWREG(FLASH_BASE + FLASH_O_FSM_PE_VH) &
~FLASH_FSM_PE_VH_PGM_VH_M) |
((value << FLASH_FSM_PE_VH_PGM_VH_S) &
FLASH_FSM_PE_VH_PGM_VH_M);
/* Configure Program Operation Setup time */
/* (FCFG1 offset 0x170 bits 31:24). */
value = (HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_E_P) &
FCFG1_FLASH_E_P_PSU_M) >>
FCFG1_FLASH_E_P_PSU_S;
HWREG(FLASH_BASE + FLASH_O_FSM_PE_OSU) =
(HWREG(FLASH_BASE + FLASH_O_FSM_PE_OSU) &
~FLASH_FSM_PE_OSU_PGM_OSU_M) |
((value << FLASH_FSM_PE_OSU_PGM_OSU_S) &
FLASH_FSM_PE_OSU_PGM_OSU_M);
/* Configure Erase Operation Setup time */
/* (FCGF1 offset 0x170 bits 23:16). */
value = (HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_E_P) &
FCFG1_FLASH_E_P_ESU_M) >>
FCFG1_FLASH_E_P_ESU_S;
HWREG(FLASH_BASE + FLASH_O_FSM_PE_OSU) =
(HWREG(FLASH_BASE + FLASH_O_FSM_PE_OSU) &
~FLASH_FSM_PE_OSU_ERA_OSU_M) |
((value << FLASH_FSM_PE_OSU_ERA_OSU_S) &
FLASH_FSM_PE_OSU_ERA_OSU_M);
/* Confgure Program Verify Setup time */
/* (FCFG1 offset 0x170 bits 15:8). */
value = (HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_E_P) &
FCFG1_FLASH_E_P_PVSU_M) >>
FCFG1_FLASH_E_P_PVSU_S;
HWREG(FLASH_BASE + FLASH_O_FSM_PE_VSU) =
(HWREG(FLASH_BASE + FLASH_O_FSM_PE_VSU) &
~FLASH_FSM_PE_VSU_PGM_VSU_M) |
((value << FLASH_FSM_PE_VSU_PGM_VSU_S) &
FLASH_FSM_PE_VSU_PGM_VSU_M);
/* Configure Erase Verify Setup time */
/* (FCFG1 offset 0x170 bits 7:0). */
value = (HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_E_P) &
FCFG1_FLASH_E_P_EVSU_M) >>
FCFG1_FLASH_E_P_EVSU_S;
HWREG(FLASH_BASE + FLASH_O_FSM_PE_VSU) =
(HWREG(FLASH_BASE + FLASH_O_FSM_PE_VSU) &
~FLASH_FSM_PE_VSU_ERA_VSU_M) |
((value << FLASH_FSM_PE_VSU_ERA_VSU_S) &
FLASH_FSM_PE_VSU_ERA_VSU_M);
/* Configure Addr to EXECUTEZ low setup time */
/* (FCFG1 offset 0x174 bits 15:12). */
value = (HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_C_E_P_R) &
FCFG1_FLASH_C_E_P_R_A_EXEZ_SETUP_M) >>
FCFG1_FLASH_C_E_P_R_A_EXEZ_SETUP_S;
HWREG(FLASH_BASE + FLASH_O_FSM_CMP_VSU) =
(HWREG(FLASH_BASE + FLASH_O_FSM_CMP_VSU) &
~FLASH_FSM_CMP_VSU_ADD_EXZ_M) |
((value << FLASH_FSM_CMP_VSU_ADD_EXZ_S) &
FLASH_FSM_CMP_VSU_ADD_EXZ_M);
/* Configure Voltage Status Count */
/* (FCFG1 offset 0x17C bits 15:12). */
value = (HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_EH_SEQ) &
FCFG1_FLASH_EH_SEQ_VSTAT_M) >>
FCFG1_FLASH_EH_SEQ_VSTAT_S;
HWREG(FLASH_BASE + FLASH_O_FSM_VSTAT) =
(HWREG(FLASH_BASE + FLASH_O_FSM_VSTAT) &
~FLASH_FSM_VSTAT_VSTAT_CNT_M) |
((value << FLASH_FSM_VSTAT_VSTAT_CNT_S) &
FLASH_FSM_VSTAT_VSTAT_CNT_M);
/* Configure Repeat Verify action setup */
/* (FCFG1 offset 0x174 bits 31:24). */
value = (HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_C_E_P_R) &
FCFG1_FLASH_C_E_P_R_RVSU_M) >>
FCFG1_FLASH_C_E_P_R_RVSU_S;
HWREG(FLASH_BASE + FLASH_O_FSM_EX_VAL) =
(HWREG(FLASH_BASE + FLASH_O_FSM_EX_VAL) &
~FLASH_FSM_EX_VAL_REP_VSU_M) |
((value << FLASH_FSM_EX_VAL_REP_VSU_S) &
FLASH_FSM_EX_VAL_REP_VSU_M);
/* Configure Maximum Programming Pulses */
/* (FCFG1 offset 0x184 bits 15:0). */
value = (HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_PP) &
FCFG1_FLASH_PP_MAX_PP_M) >>
FCFG1_FLASH_PP_MAX_PP_S;
HWREG(FLASH_BASE + FLASH_O_FSM_PRG_PUL) =
(HWREG(FLASH_BASE + FLASH_O_FSM_PRG_PUL) &
~FLASH_FSM_PRG_PUL_MAX_PRG_PUL_M) |
((value << FLASH_FSM_PRG_PUL_MAX_PRG_PUL_S) &
FLASH_FSM_PRG_PUL_MAX_PRG_PUL_M);
/* Configure Beginning level for VHVCT used during erase modes */
/* (FCFG1 offset 0x180 bits 31:16). */
value = (HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_VHV_E) &
FCFG1_FLASH_VHV_E_VHV_E_START_M) >>
FCFG1_FLASH_VHV_E_VHV_E_START_S;
HWREG(FLASH_BASE + FLASH_O_FSM_PRG_PUL) =
(HWREG(FLASH_BASE + FLASH_O_FSM_PRG_PUL) &
~FLASH_FSM_PRG_PUL_BEG_EC_LEVEL_M) |
((value << FLASH_FSM_PRG_PUL_BEG_EC_LEVEL_S) &
FLASH_FSM_PRG_PUL_BEG_EC_LEVEL_M);
/* Configure Maximum EC Level */
/* (FCFG1 offset 0x2B0 bits 21:18). */
value = (HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_OTP_DATA3) &
FCFG1_FLASH_OTP_DATA3_MAX_EC_LEVEL_M) >>
FCFG1_FLASH_OTP_DATA3_MAX_EC_LEVEL_S;
HWREG(FLASH_BASE + FLASH_O_FSM_ERA_PUL) =
(HWREG(FLASH_BASE + FLASH_O_FSM_ERA_PUL) &
~FLASH_FSM_ERA_PUL_MAX_EC_LEVEL_M) |
((value << FLASH_FSM_ERA_PUL_MAX_EC_LEVEL_S) &
FLASH_FSM_ERA_PUL_MAX_EC_LEVEL_M);
/* Configure Maximum Erase Pulses */
/* (FCFG1 offset 0x188 bits 31:16). */
value = (HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_PROG_EP) &
FCFG1_FLASH_PROG_EP_MAX_EP_M) >>
FCFG1_FLASH_PROG_EP_MAX_EP_S;
HWREG(FLASH_BASE + FLASH_O_FSM_ERA_PUL) =
(HWREG(FLASH_BASE + FLASH_O_FSM_ERA_PUL) &
~FLASH_FSM_ERA_PUL_MAX_ERA_PUL_M) |
((value << FLASH_FSM_ERA_PUL_MAX_ERA_PUL_S) &
FLASH_FSM_ERA_PUL_MAX_ERA_PUL_M);
/* Configure the VHVCT Step Size. This is the number of erase pulses that
must be completed for each level before the FSM increments the
CUR_EC_LEVEL to the next higher level. Actual erase pulses per level
equals (EC_STEP_SIZE +1). The stepping is only needed for the VHVCT
voltage. */
/* (FCFG1 offset 0x2B0 bits 31:23). */
value = (HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_OTP_DATA3) &
FCFG1_FLASH_OTP_DATA3_EC_STEP_SIZE_M) >>
FCFG1_FLASH_OTP_DATA3_EC_STEP_SIZE_S;
HWREG(FLASH_BASE + FLASH_O_FSM_STEP_SIZE) =
(HWREG(FLASH_BASE + FLASH_O_FSM_STEP_SIZE) &
~FLASH_FSM_STEP_SIZE_EC_STEP_SIZE_M) |
((value << FLASH_FSM_STEP_SIZE_EC_STEP_SIZE_S) &
FLASH_FSM_STEP_SIZE_EC_STEP_SIZE_M);
/* Configure the hight of each EC step. This is the number of counts that
the CUR_EC_LEVEL will increment when going to a new level. Actual count
size equals (EC_STEP_HEIGHT + 1). The stepping applies only to the VHVCT
voltage.
The read trim value is decremented by 1 before written to the register
since actual counts equals (register value + 1). */
/* (FCFG1 offset 0x180 bits 15:0). */
value = (HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_VHV_E) &
FCFG1_FLASH_VHV_E_VHV_E_STEP_HIGHT_M) >>
FCFG1_FLASH_VHV_E_VHV_E_STEP_HIGHT_S;
HWREG(FLASH_BASE + FLASH_O_FSM_EC_STEP_HEIGHT) = ((value - 1) &
FLASH_FSM_EC_STEP_HEIGHT_EC_STEP_HEIGHT_M);
/* Configure Precondition used in erase operations */
/* (FCFG1 offset 0x2B0 bit 22). */
value = (HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_OTP_DATA3) &
FCFG1_FLASH_OTP_DATA3_DO_PRECOND_M) >>
FCFG1_FLASH_OTP_DATA3_DO_PRECOND_S;
HWREG(FLASH_BASE + FLASH_O_FSM_ST_MACHINE) =
(HWREG(FLASH_BASE + FLASH_O_FSM_ST_MACHINE) &
~FLASH_FSM_ST_MACHINE_DO_PRECOND_M) |
((value << FLASH_FSM_ST_MACHINE_DO_PRECOND_S) &
FLASH_FSM_ST_MACHINE_DO_PRECOND_M);
/* Enable the recommended Good Time function. */
HWREG(FLASH_BASE + FLASH_O_FSM_ST_MACHINE) |=
FLASH_FSM_ST_MACHINE_ONE_TIME_GOOD;
/* Disable write access to FSM registers. */
HWREG(FLASH_BASE + FLASH_O_FSM_WR_ENA) = FSM_REG_WRT_DISABLE;
/* Configure the voltage registers */
/* Unlock voltage registers (0x2080 - 0x2098). */
HWREG(FLASH_BASE + FLASH_O_FLOCK) = 0xAAAA;
/* Configure voltage level for the specified pump voltage of high
voltage supply input during erase operation VHVCT_E and TRIM13_E */
/* (FCFG1 offset 0x190 bits[3:0] and bits[11:8]). */
temp_val = HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_VHV);
value = ((temp_val & FCFG1_FLASH_VHV_TRIM13_E_M)>>
FCFG1_FLASH_VHV_TRIM13_E_S) << FLASH_FVHVCT1_TRIM13_E_S;
value |= ((temp_val & FCFG1_FLASH_VHV_VHV_E_M)>>
FCFG1_FLASH_VHV_VHV_E_S) << FLASH_FVHVCT1_VHVCT_E_S;
HWREG(FLASH_BASE + FLASH_O_FVHVCT1) = (HWREG(FLASH_BASE + FLASH_O_FVHVCT1) &
~(FLASH_FVHVCT1_TRIM13_E_M | FLASH_FVHVCT1_VHVCT_E_M)) | value;
/* Configure voltage level for the specified pump voltage of high voltage
supply input during program verify operation VHVCT_PV and TRIM13_PV */
/* (OTP offset 0x194 bits[19:16] and bits[27:24]). */
temp_val = HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_VHV_PV);
value = ((temp_val & FCFG1_FLASH_VHV_PV_TRIM13_PV_M) >>
FCFG1_FLASH_VHV_PV_TRIM13_PV_S) << FLASH_FVHVCT1_TRIM13_PV_S;
value |= ((temp_val & FCFG1_FLASH_VHV_PV_VHV_PV_M) >>
FCFG1_FLASH_VHV_PV_VHV_PV_S) << FLASH_FVHVCT1_VHVCT_PV_S;
HWREG(FLASH_BASE + FLASH_O_FVHVCT1) = (HWREG(FLASH_BASE + FLASH_O_FVHVCT1) &
~(FLASH_FVHVCT1_TRIM13_PV_M | FLASH_FVHVCT1_VHVCT_PV_M)) | value;
/* Configure voltage level for the specified pump voltage of high voltage
supply input during program operation VHVCT_P and TRIM13_P */
/* (FCFG1 offset 0x190 bits[19:16] and bits[27:24]). */
temp_val = HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_VHV);
value = ((temp_val & FCFG1_FLASH_VHV_TRIM13_P_M) >>
FCFG1_FLASH_VHV_TRIM13_P_S) << FLASH_FVHVCT2_TRIM13_P_S;
value |= ((temp_val & FCFG1_FLASH_VHV_VHV_P_M) >>
FCFG1_FLASH_VHV_VHV_P_S) << FLASH_FVHVCT2_VHVCT_P_S;
HWREG(FLASH_BASE + FLASH_O_FVHVCT2) = (HWREG(FLASH_BASE + FLASH_O_FVHVCT2) &
~(FLASH_FVHVCT2_TRIM13_P_M | FLASH_FVHVCT2_VHVCT_P_M)) | value;
/* Configure voltage level for the specified pump voltage of wordline power
supply for read mode */
/* (FCFG1 offset 0x198 Bits 15:8). */
value = (HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_V) &
FCFG1_FLASH_V_V_READ_M) >> FCFG1_FLASH_V_V_READ_S;
HWREG(FLASH_BASE + FLASH_O_FVREADCT) =
(HWREG(FLASH_BASE + FLASH_O_FVREADCT) &
~FLASH_FVREADCT_VREADCT_M) |
((value << FLASH_FVREADCT_VREADCT_S) &
FLASH_FVREADCT_VREADCT_M);
/* Configure the voltage level for the VCG 2.5 CT pump voltage */
/* (FCFG1 offset 0x194 bits 15:8). */
value = (HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_VHV_PV) &
FCFG1_FLASH_VHV_PV_VCG2P5_M) >>
FCFG1_FLASH_VHV_PV_VCG2P5_S;
HWREG(FLASH_BASE + FLASH_O_FVNVCT) =
(HWREG(FLASH_BASE + FLASH_O_FVNVCT) &
~FLASH_FVNVCT_VCG2P5CT_M) |
((value << FLASH_FVNVCT_VCG2P5CT_S) &
FLASH_FVNVCT_VCG2P5CT_M);
/* Configure the voltage level for the specified pump voltage of high
current power input during program operation */
/* (FCFG1 offset 0x198 bits 31:24). */
value = (HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_V) &
FCFG1_FLASH_V_VSL_P_M) >>
FCFG1_FLASH_V_VSL_P_S;
HWREG(FLASH_BASE + FLASH_O_FVSLP) =
(HWREG(FLASH_BASE + FLASH_O_FVSLP) &
~FLASH_FVSLP_VSL_P_M) |
((value << FLASH_FVSLP_VSL_P_S) &
FLASH_FVSLP_VSL_P_M);
/* Configure the voltage level for the specified pump voltage of wordline
power supply during programming operations */
/* (OTP offset 0x198 bits 23:16). */
value = (HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_V) &
FCFG1_FLASH_V_VWL_P_M) >>
FCFG1_FLASH_V_VWL_P_S;
HWREG(FLASH_BASE + FLASH_O_FVWLCT) =
(HWREG(FLASH_BASE + FLASH_O_FVWLCT) &
~FLASH_FVWLCT_VWLCT_P_M) |
((value << FLASH_FVWLCT_VWLCT_P_S) &
FLASH_FVWLCT_VWLCT_P_M);
/* Configure the pump's TRIM_1P7 port pins. */
/* (FCFG1 offset 0x2B0 bits 17:16). */
value = (HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_OTP_DATA3) &
FCFG1_FLASH_OTP_DATA3_TRIM_1P7_M) >>
FCFG1_FLASH_OTP_DATA3_TRIM_1P7_S;
HWREG(FLASH_BASE + FLASH_O_FSEQPMP) =
(HWREG(FLASH_BASE + FLASH_O_FSEQPMP) &
~FLASH_FSEQPMP_TRIM_1P7_M) |
((value << FLASH_FSEQPMP_TRIM_1P7_S) &
FLASH_FSEQPMP_TRIM_1P7_M);
/* Lock the voltage registers. */
HWREG(FLASH_BASE + FLASH_O_FLOCK) = 0x55AA;
/* Set trimmed flag. */
HWREG(FLASH_BASE + FLASH_O_FWLOCK) = 5;
HWREG(FLASH_BASE + FLASH_O_FWFLAG) |= FW_WRT_TRIMMED;
HWREG(FLASH_BASE + FLASH_O_FWLOCK) = 0;
}
/******************************************************************************
*
* Used to scale the TI OTP values based on the FClk scaling value.
*
******************************************************************************/
static uint32_t scale_cycle_values(uint32_t specified_timing,
uint32_t scale_value)
{
uint32_t scaled_value = (specified_timing * scale_value) >> 6;
return scaled_value;
}
/******************************************************************************
*
* Used to set flash in read mode.
*
* Flash is configured with values loaded from OTP dependent on the current
* regulator mode.
*
******************************************************************************/
static void set_read_mode(void)
{
uint32_t trim_value;
uint32_t value;
/* Configure the STANDBY_MODE_SEL, STANDBY_PW_SEL, DIS_STANDBY, DIS_IDLE,
VIN_AT_X and VIN_BY_PASS for read mode */
if (HWREG(AON_PMCTL_BASE + AON_PMCTL_O_PWRCTL) &
AON_PMCTL_PWRCTL_EXT_REG_MODE) {
/* Select trim values for external regulator mode:
Configure STANDBY_MODE_SEL (OTP offset 0x308 bit 7)
Configure STANDBY_PW_SEL (OTP offset 0x308 bit 6:5)
Must be done while the register bit field CONFIG.DIS_STANDBY = 1 */
HWREG(FLASH_BASE + FLASH_O_CFG) |= FLASH_CFG_DIS_STANDBY;
trim_value =
HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_OTP_DATA4);
value = ((trim_value &
FCFG1_FLASH_OTP_DATA4_STANDBY_MODE_SEL_EXT_RD_M) >>
FCFG1_FLASH_OTP_DATA4_STANDBY_MODE_SEL_EXT_RD_S) <<
FLASH_CFG_STANDBY_MODE_SEL_S;
value |= ((trim_value &
FCFG1_FLASH_OTP_DATA4_STANDBY_PW_SEL_EXT_RD_M) >>
FCFG1_FLASH_OTP_DATA4_STANDBY_PW_SEL_EXT_RD_S) <<
FLASH_CFG_STANDBY_PW_SEL_S;
/* Configure DIS_STANDBY (OTP offset 0x308 bit 4).
Configure DIS_IDLE (OTP offset 0x308 bit 3). */
value |= ((trim_value &
(FCFG1_FLASH_OTP_DATA4_DIS_STANDBY_EXT_RD_M |
FCFG1_FLASH_OTP_DATA4_DIS_IDLE_EXT_RD_M)) >>
FCFG1_FLASH_OTP_DATA4_DIS_IDLE_EXT_RD_S) <<
FLASH_CFG_DIS_IDLE_S;
HWREG(FLASH_BASE + FLASH_O_CFG) = (HWREG(FLASH_BASE + FLASH_O_CFG) &
~(FLASH_CFG_STANDBY_MODE_SEL_M | FLASH_CFG_STANDBY_PW_SEL_M |
FLASH_CFG_DIS_STANDBY_M | FLASH_CFG_DIS_IDLE_M)) | value;
/* Check if sample and hold functionality is disabled. */
if (HWREG(FLASH_BASE + FLASH_O_CFG) & FLASH_CFG_DIS_IDLE) {
/* Wait for disabled sample and hold functionality to be stable. */
while (!(HWREG(FLASH_BASE+FLASH_O_STAT) & FLASH_STAT_SAMHOLD_DIS))
;
}
/* Configure VIN_AT_X (OTP offset 0x308 bits 2:0) */
value = ((trim_value &
FCFG1_FLASH_OTP_DATA4_VIN_AT_X_EXT_RD_M) >>
FCFG1_FLASH_OTP_DATA4_VIN_AT_X_EXT_RD_S) <<
FLASH_FSEQPMP_VIN_AT_X_S;
/* Configure VIN_BY_PASS which is dependent on the VIN_AT_X value.
If VIN_AT_X = 7 then VIN_BY_PASS should be 0 otherwise
VIN_BY_PASS should be 1 */
if (((value & FLASH_FSEQPMP_VIN_AT_X_M) >>
FLASH_FSEQPMP_VIN_AT_X_S) != 0x7)
value |= FLASH_FSEQPMP_VIN_BY_PASS;
HWREG(FLASH_BASE + FLASH_O_FLOCK) = 0xAAAA;
HWREG(FLASH_BASE + FLASH_O_FSEQPMP) =
(HWREG(FLASH_BASE + FLASH_O_FSEQPMP) &
~(FLASH_FSEQPMP_VIN_BY_PASS_M |
FLASH_FSEQPMP_VIN_AT_X_M)) | value;
HWREG(FLASH_BASE + FLASH_O_FLOCK) = 0x55AA;
} else {
/* Select trim values for internal regulator mode:
Configure STANDBY_MODE_SEL (OTP offset 0x308 bit 15)
COnfigure STANDBY_PW_SEL (OTP offset 0x308 bit 14:13)
Must be done while the register bit field CONFIG.DIS_STANDBY = 1 */
HWREG(FLASH_BASE + FLASH_O_CFG) |= FLASH_CFG_DIS_STANDBY;
trim_value =
HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_OTP_DATA4);
value = ((trim_value &
FCFG1_FLASH_OTP_DATA4_STANDBY_MODE_SEL_INT_RD_M) >>
FCFG1_FLASH_OTP_DATA4_STANDBY_MODE_SEL_INT_RD_S) <<
FLASH_CFG_STANDBY_MODE_SEL_S;
value |= ((trim_value &
FCFG1_FLASH_OTP_DATA4_STANDBY_PW_SEL_INT_RD_M) >>
FCFG1_FLASH_OTP_DATA4_STANDBY_PW_SEL_INT_RD_S) <<
FLASH_CFG_STANDBY_PW_SEL_S;
/* Configure DIS_STANDBY (OTP offset 0x308 bit 12).
Configure DIS_IDLE (OTP offset 0x308 bit 11). */
value |= ((trim_value &
(FCFG1_FLASH_OTP_DATA4_DIS_STANDBY_INT_RD_M |
FCFG1_FLASH_OTP_DATA4_DIS_IDLE_INT_RD_M)) >>
FCFG1_FLASH_OTP_DATA4_DIS_IDLE_INT_RD_S) <<
FLASH_CFG_DIS_IDLE_S;
HWREG(FLASH_BASE + FLASH_O_CFG) = (HWREG(FLASH_BASE + FLASH_O_CFG) &
~(FLASH_CFG_STANDBY_MODE_SEL_M | FLASH_CFG_STANDBY_PW_SEL_M |
FLASH_CFG_DIS_STANDBY_M | FLASH_CFG_DIS_IDLE_M)) | value;
/* Check if sample and hold functionality is disabled. */
if (HWREG(FLASH_BASE + FLASH_O_CFG) & FLASH_CFG_DIS_IDLE) {
/* Wait for disabled sample and hold functionality to be stable. */
while (!(HWREG(FLASH_BASE + FLASH_O_STAT) & FLASH_STAT_SAMHOLD_DIS))
;
}
/* Configure VIN_AT_X (OTP offset 0x308 bits 10:8) */
value = (((trim_value &
FCFG1_FLASH_OTP_DATA4_VIN_AT_X_INT_RD_M) >>
FCFG1_FLASH_OTP_DATA4_VIN_AT_X_INT_RD_S) <<
FLASH_FSEQPMP_VIN_AT_X_S);
/* Configure VIN_BY_PASS which is dependent on the VIN_AT_X value.
If VIN_AT_X = 7 then VIN_BY_PASS should be 0 otherwise
VIN_BY_PASS should be 1 */
if (((value & FLASH_FSEQPMP_VIN_AT_X_M) >>
FLASH_FSEQPMP_VIN_AT_X_S) != 0x7)
value |= FLASH_FSEQPMP_VIN_BY_PASS;
HWREG(FLASH_BASE + FLASH_O_FLOCK) = 0xAAAA;
HWREG(FLASH_BASE + FLASH_O_FSEQPMP) =
(HWREG(FLASH_BASE + FLASH_O_FSEQPMP) &
~(FLASH_FSEQPMP_VIN_BY_PASS_M |
FLASH_FSEQPMP_VIN_AT_X_M)) | value;
HWREG(FLASH_BASE + FLASH_O_FLOCK) = 0x55AA;
}
}
/******************************************************************************
*
* Used to set flash in write mode.
*
* Flash is configured with values loaded from OTP dependent on the current
* regulator mode.
*
******************************************************************************/
static void set_write_mode(void)
{
uint32_t trim_value;
uint32_t value;
/* Configure the STANDBY_MODE_SEL, STANDBY_PW_SEL, DIS_STANDBY, DIS_IDLE,
VIN_AT_X and VIN_BY_PASS for program/erase mode */
if (HWREG(AON_PMCTL_BASE + AON_PMCTL_O_PWRCTL) &
AON_PMCTL_PWRCTL_EXT_REG_MODE) {
/* Select trim values for external regulator mode:
Configure STANDBY_MODE_SEL (OTP offset 0x308 bit 23)
Configure STANDBY_PW_SEL (OTP offset 0x308 bit 22:21)
Must be done while the register bit field CONFIG.DIS_STANDBY = 1 */
HWREG(FLASH_BASE + FLASH_O_CFG) |= FLASH_CFG_DIS_STANDBY;
trim_value =
HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_OTP_DATA4);
value = ((trim_value &
FCFG1_FLASH_OTP_DATA4_STANDBY_MODE_SEL_EXT_WRT_M) >>
FCFG1_FLASH_OTP_DATA4_STANDBY_MODE_SEL_EXT_WRT_S) <<
FLASH_CFG_STANDBY_MODE_SEL_S;
value |= ((trim_value &
FCFG1_FLASH_OTP_DATA4_STANDBY_PW_SEL_EXT_WRT_M) >>
FCFG1_FLASH_OTP_DATA4_STANDBY_PW_SEL_EXT_WRT_S) <<
FLASH_CFG_STANDBY_PW_SEL_S;
/* Configure DIS_STANDBY (OTP offset 0x308 bit 20).
Configure DIS_IDLE (OTP offset 0x308 bit 19). */
value |= ((trim_value &
(FCFG1_FLASH_OTP_DATA4_DIS_STANDBY_EXT_WRT_M |
FCFG1_FLASH_OTP_DATA4_DIS_IDLE_EXT_WRT_M)) >>
FCFG1_FLASH_OTP_DATA4_DIS_IDLE_EXT_WRT_S) <<
FLASH_CFG_DIS_IDLE_S;
HWREG(FLASH_BASE + FLASH_O_CFG) = (HWREG(FLASH_BASE + FLASH_O_CFG) &
~(FLASH_CFG_STANDBY_MODE_SEL_M | FLASH_CFG_STANDBY_PW_SEL_M |
FLASH_CFG_DIS_STANDBY_M | FLASH_CFG_DIS_IDLE_M)) | value;
/* Check if sample and hold functionality is disabled. */
if (HWREG(FLASH_BASE + FLASH_O_CFG) & FLASH_CFG_DIS_IDLE) {
/* Wait for disabled sample and hold functionality to be stable. */
while (!(HWREG(FLASH_BASE + FLASH_O_STAT) & FLASH_STAT_SAMHOLD_DIS))
;
}
/* Configure VIN_AT_X (OTP offset 0x308 bits 18:16) */
value = ((trim_value &
FCFG1_FLASH_OTP_DATA4_VIN_AT_X_EXT_WRT_M) >>
FCFG1_FLASH_OTP_DATA4_VIN_AT_X_EXT_WRT_S) <<
FLASH_FSEQPMP_VIN_AT_X_S;
/* Configure VIN_BY_PASS which is dependent on the VIN_AT_X value.
If VIN_AT_X = 7 then VIN_BY_PASS should be 0 otherwise
VIN_BY_PASS should be 1 */
if (((value & FLASH_FSEQPMP_VIN_AT_X_M) >>
FLASH_FSEQPMP_VIN_AT_X_S) != 0x7)
value |= FLASH_FSEQPMP_VIN_BY_PASS;
HWREG(FLASH_BASE + FLASH_O_FLOCK) = 0xAAAA;
HWREG(FLASH_BASE + FLASH_O_FSEQPMP) =
(HWREG(FLASH_BASE + FLASH_O_FSEQPMP) &
~(FLASH_FSEQPMP_VIN_BY_PASS_M |
FLASH_FSEQPMP_VIN_AT_X_M)) | value;
HWREG(FLASH_BASE + FLASH_O_FLOCK) = 0x55AA;
} else {
/* Select trim values for internal regulator mode:
Configure STANDBY_MODE_SEL (OTP offset 0x308 bit 31)
COnfigure STANDBY_PW_SEL (OTP offset 0x308 bit 30:29)
Must be done while the register bit field CONFIG.DIS_STANDBY = 1 */
HWREG(FLASH_BASE + FLASH_O_CFG) |= FLASH_CFG_DIS_STANDBY;
trim_value =
HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_OTP_DATA4);
value = ((trim_value &
FCFG1_FLASH_OTP_DATA4_STANDBY_MODE_SEL_INT_WRT_M) >>
FCFG1_FLASH_OTP_DATA4_STANDBY_MODE_SEL_INT_WRT_S) <<
FLASH_CFG_STANDBY_MODE_SEL_S;
value |= ((trim_value &
FCFG1_FLASH_OTP_DATA4_STANDBY_PW_SEL_INT_WRT_M) >>
FCFG1_FLASH_OTP_DATA4_STANDBY_PW_SEL_INT_WRT_S) <<
FLASH_CFG_STANDBY_PW_SEL_S;
/* Configure DIS_STANDBY (OTP offset 0x308 bit 28).
Configure DIS_IDLE (OTP offset 0x308 bit 27). */
value |= ((trim_value &
(FCFG1_FLASH_OTP_DATA4_DIS_STANDBY_INT_WRT_M |
FCFG1_FLASH_OTP_DATA4_DIS_IDLE_INT_WRT_M)) >>
FCFG1_FLASH_OTP_DATA4_DIS_IDLE_INT_WRT_S) <<
FLASH_CFG_DIS_IDLE_S;
HWREG(FLASH_BASE + FLASH_O_CFG) = (HWREG(FLASH_BASE + FLASH_O_CFG) &
~(FLASH_CFG_STANDBY_MODE_SEL_M | FLASH_CFG_STANDBY_PW_SEL_M |
FLASH_CFG_DIS_STANDBY_M | FLASH_CFG_DIS_IDLE_M)) | value;
/* Check if sample and hold functionality is disabled. */
if (HWREG(FLASH_BASE + FLASH_O_CFG) & FLASH_CFG_DIS_IDLE) {
/* Wait for disabled sample and hold functionality to be stable. */
while (!(HWREG(FLASH_BASE + FLASH_O_STAT) & FLASH_STAT_SAMHOLD_DIS))
;
}
/* Configure VIN_AT_X (OTP offset 0x308 bits 26:24) */
value = ((trim_value &
FCFG1_FLASH_OTP_DATA4_VIN_AT_X_INT_WRT_M) >>
FCFG1_FLASH_OTP_DATA4_VIN_AT_X_INT_WRT_S) <<
FLASH_FSEQPMP_VIN_AT_X_S;
/* Configure VIN_BY_PASS which is dependent on the VIN_AT_X value.
If VIN_AT_X = 7 then VIN_BY_PASS should be 0 otherwise
VIN_BY_PASS should be 1 */
if (((value & FLASH_FSEQPMP_VIN_AT_X_M) >>
FLASH_FSEQPMP_VIN_AT_X_S) != 0x7)
value |= FLASH_FSEQPMP_VIN_BY_PASS;
HWREG(FLASH_BASE + FLASH_O_FLOCK) = 0xAAAA;
HWREG(FLASH_BASE + FLASH_O_FSEQPMP) =
(HWREG(FLASH_BASE + FLASH_O_FSEQPMP) &
~(FLASH_FSEQPMP_VIN_BY_PASS_M |
FLASH_FSEQPMP_VIN_AT_X_M)) | value;
HWREG(FLASH_BASE + FLASH_O_FLOCK) = 0x55AA;
}
}

View File

@ -0,0 +1,378 @@
/******************************************************************************
*
* Copyright (C) 2016-2018 Texas Instruments Incorporated - http://www.ti.com/
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* distribution.
*
* Neither the name of Texas Instruments Incorporated nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************/
#ifndef OPENOCD_LOADERS_FLASH_CC26XX_FLASH_H
#define OPENOCD_LOADERS_FLASH_CC26XX_FLASH_H
#ifdef __cplusplus
extern "C"
{
#endif
#include <stdint.h>
#include <stdbool.h>
#include "hw_regs.h"
/* Location of flash in memory map */
#define FLASHMEM_BASE 0
/* Defines to access flash API calls in ROM */
#define ROM_API_TABLE ((uint32_t *) 0x10000180)
#define ROM_VERSION (ROM_API_TABLE[0])
#define ROM_API_FLASH_TABLE ((uint32_t *) (ROM_API_TABLE[10]))
#if defined(DEVICE_CC26X2)
/* Agama (CC26x2) specific definitions */
#define FLASH_ERASE_SIZE 8192
/* Agama (and Agama 1M) has a maximum of 132 flash sectors (1056KB / 8KB) */
#define FLASH_MAX_SECTOR_COUNT 132
#define FLASH_SECTOR_BASE_M 0xFFFFE000
/* Bootloader Configuration */
#define CCFG_O_BL_CONFIG 0x00001FD8
#elif defined(DEVICE_CC26X0)
/* Chameleon (CC26x0) specific definitions */
#define FLASH_ERASE_SIZE 4096
/* Chameleon has a maximum of 32 flash sectors (128KB / 4KB) */
#define FLASH_MAX_SECTOR_COUNT 32
#define FLASH_SECTOR_BASE_M 0xFFFFF000
/* Bootloader Configuration */
#define CCFG_O_BL_CONFIG 0x00000FD8
#else
#error No DEVICE defined.
#endif
/******************************************************************************
*
* Values that can be returned from the API functions
*
******************************************************************************/
#define FAPI_STATUS_SUCCESS 0x00000000 /* Function completed successfully */
#define FAPI_STATUS_FSM_BUSY 0x00000001 /* FSM is Busy */
#define FAPI_STATUS_FSM_READY 0x00000002 /* FSM is Ready */
#define FAPI_STATUS_INCORRECT_DATABUFFER_LENGTH \
0x00000003 /* Incorrect parameter value */
#define FAPI_STATUS_FSM_ERROR 0x00000004 /* Operation failed */
/******************************************************************************
*
* Define used by the flash programming and erase functions
*
******************************************************************************/
#define ADDR_OFFSET (0x1F800000 - FLASHMEM_BASE)
/******************************************************************************
*
* Define used for access to factory configuration area.
*
******************************************************************************/
#define FCFG1_OFFSET 0x1000
/******************************************************************************
*
* Define for the clock frequencey input to the flash module in number of MHz
*
******************************************************************************/
#define FLASH_MODULE_CLK_FREQ 48
/******************************************************************************
*
* Defined values for Flash State Machine commands
*
******************************************************************************/
typedef enum {
FAPI_PROGRAM_DATA = 0x0002, /* Program data. */
FAPI_ERASE_SECTOR = 0x0006, /* Erase sector. */
FAPI_ERASE_BANK = 0x0008, /* Erase bank. */
FAPI_VALIDATE_SECTOR = 0x000E, /* Validate sector. */
FAPI_CLEAR_STATUS = 0x0010, /* Clear status. */
FAPI_PROGRAM_RESUME = 0x0014, /* Program resume. */
FAPI_ERASE_RESUME = 0x0016, /* Erase resume. */
FAPI_CLEAR_MORE = 0x0018, /* Clear more. */
FAPI_PROGRAM_SECTOR = 0x0020, /* Program sector. */
FAPI_ERASE_OTP = 0x0030 /* Erase OTP. */
} flash_state_command_t;
/******************************************************************************
*
* Defines for values written to the FLASH_O_FSM_WR_ENA register
*
******************************************************************************/
#define FSM_REG_WRT_ENABLE 5
#define FSM_REG_WRT_DISABLE 2
/******************************************************************************
*
* Defines for the bank power mode field the FLASH_O_FBFALLBACK register
*
******************************************************************************/
#define FBFALLBACK_SLEEP 0
#define FBFALLBACK_DEEP_STDBY 1
#define FBFALLBACK_ACTIVE 3
/******************************************************************************
*
* Defines for the bank grace period and pump grace period
*
******************************************************************************/
#define FLASH_BAGP 0x14
#define FLASH_PAGP 0x14
/******************************************************************************
*
* Defines for the FW flag bits in the FLASH_O_FWFLAG register
*
******************************************************************************/
#define FW_WRT_TRIMMED 0x00000001
/******************************************************************************
*
* Defines used by the flash programming functions
*
******************************************************************************/
typedef volatile uint8_t fwp_write_byte;
#define FWPWRITE_BYTE_ADDRESS \
((fwp_write_byte *)((FLASH_BASE + FLASH_O_FWPWRITE0)))
/******************************************************************************
*
* Define for FSM command execution
*
******************************************************************************/
#define FLASH_CMD_EXEC 0x15
/******************************************************************************
*
* Get size of a flash sector in number of bytes.
*
* This function will return the size of a flash sector in number of bytes.
*
* Returns size of a flash sector in number of bytes.
*
******************************************************************************/
static inline uint32_t flash_sector_size_get(void)
{
uint32_t sector_size_in_kbyte;
sector_size_in_kbyte = (HWREG(FLASH_BASE + FLASH_O_FCFG_B0_SSIZE0) &
FLASH_FCFG_B0_SSIZE0_B0_SECT_SIZE_M) >>
FLASH_FCFG_B0_SSIZE0_B0_SECT_SIZE_S;
/* Return flash sector size in number of bytes. */
return sector_size_in_kbyte * 1024;
}
/******************************************************************************
*
* Get the size of the flash.
*
* This function returns the size of the flash main bank in number of bytes.
*
* Returns the flash size in number of bytes.
*
******************************************************************************/
static inline uint32_t flash_size_get(void)
{
uint32_t num_of_sectors;
/* Get number of flash sectors */
num_of_sectors = (HWREG(FLASH_BASE + FLASH_O_FLASH_SIZE) &
FLASH_FLASH_SIZE_SECTORS_M) >>
FLASH_FLASH_SIZE_SECTORS_S;
/* Return flash size in number of bytes */
return num_of_sectors * flash_sector_size_get();
}
/******************************************************************************
*
* Checks if the Flash state machine has detected an error.
*
* This function returns the status of the Flash State Machine indicating if
* an error is detected or not. Primary use is to check if an Erase or
* Program operation has failed.
*
* Please note that code can not execute in flash while any part of the flash
* is being programmed or erased. This function must be called from ROM or
* SRAM while any part of the flash is being programmed or erased.
*
* Returns status of Flash state machine:
* FAPI_STATUS_FSM_ERROR
* FAPI_STATUS_SUCCESS
*
******************************************************************************/
static inline uint32_t flash_check_fsm_for_error(void)
{
if (HWREG(FLASH_BASE + FLASH_O_FMSTAT) & FLASH_FMSTAT_CSTAT)
return FAPI_STATUS_FSM_ERROR;
else
return FAPI_STATUS_SUCCESS;
}
/******************************************************************************
*
* Checks if the Flash state machine is ready.
*
* This function returns the status of the Flash State Machine indicating if
* it is ready to accept a new command or not. Primary use is to check if an
* Erase or Program operation has finished.
*
* Please note that code can not execute in flash while any part of the flash
* is being programmed or erased. This function must be called from ROM or
* SRAM while any part of the flash is being programmed or erased.
*
* Returns readiness status of Flash state machine:
* FAPI_STATUS_FSM_READY
* FAPI_STATUS_FSM_BUSY
*
******************************************************************************/
static inline uint32_t flash_check_fsm_for_ready(void)
{
if (HWREG(FLASH_BASE + FLASH_O_STAT) & FLASH_STAT_BUSY)
return FAPI_STATUS_FSM_BUSY;
else
return FAPI_STATUS_FSM_READY;
}
/******************************************************************************
*
* Erase a flash sector.
*
* This function will erase the specified flash sector. The function will
* not return until the flash sector has been erased or an error condition
* occurred. If flash top sector is erased the function will program the
* the device security data bytes with default values. The device security
* data located in the customer configuration area of the flash top sector,
* must have valid values at all times. These values affect the configuration
* of the device during boot.
*
* Please note that code can not execute in flash while any part of the flash
* is being programmed or erased. This function must only be executed from ROM
* or SRAM.
*
* sector_address is the starting address in flash of the sector to be
* erased.
*
* Returns the status of the sector erase:
* FAPI_STATUS_SUCCESS : Success.
* FAPI_STATUS_INCORRECT_DATABUFFER_LENGTH : Invalid argument.
* FAPI_STATUS_FSM_ERROR : Programming error was encountered.
*
******************************************************************************/
extern uint32_t flash_sector_erase(uint32_t sector_address);
/******************************************************************************
*
* Erase all unprotected sectors in the flash main bank.
*
* This function will erase all unprotected flash sectors. The function will
* not return until the flash sectors has been erased or an error condition
* occurred. Since the flash top sector is erased the function will program the
* the device security data bytes with default values. The device security
* data located in the customer configuration area of the flash top sector,
* must have valid values at all times. These values affect the configuration
* of the device during boot. The execution time of the operation increases if
* erase precondition is forced. This will cause the flash module to first
* program all 1 bits in the bank to 0 before the actual erase is started.
*
* force_precondition controls if erase precondition should be forced.
*
* Returns the status of the sector erase:
* FAPI_STATUS_SUCCESS : Success
* FAPI_STATUS_FSM_ERROR : Erase error was encountered.
*
******************************************************************************/
extern uint32_t flash_bank_erase(bool force_precondition);
/******************************************************************************
*
* Programs unprotected main bank flash sectors.
*
* This function will program a sequence of bytes into the on-chip flash.
* Programming each location consists of the result of an AND operation
* of the new data and the existing data; in other words bits that contain
* 1 can remain 1 or be changed to 0, but bits that are 0 cannot be changed
* to 1. Therefore, a byte can be programmed multiple times as long as these
* rules are followed; if a program operation attempts to change a 0 bit to
* a 1 bit, that bit will not have its value changed.
*
* This function will not return until the data has been programmed or an
* programming error has occurred.
*
* Please note that code can not execute in flash while any part of the flash
* is being programmed or erased. This function must only be executed from ROM
* or SRAM.
*
* The data_buffer pointer cannot point to flash.
*
* data_buffer is a pointer to the data to be programmed.
* address is the starting address in flash to be programmed.
* count is the number of bytes to be programmed.
*
* Returns status of the flash programming:
* FAPI_STATUS_SUCCESS : Success.
* FAPI_STATUS_INCORRECT_DATABUFFER_LENGTH : Too many bytes were requested.
* FAPI_STATUS_FSM_ERROR : Programming error was encountered.
*
******************************************************************************/
extern uint32_t flash_program(uint8_t *data_buffer, uint32_t address,
uint32_t count);
/******************************************************************************
*
* Disables all sectors for erase and programming on the active bank.
*
* This function disables all sectors for erase and programming on the active
* bank and enables the Idle Reading Power reduction mode if no low power
* mode is configured. Furthermore, an additional level of protection from
* erase is enabled.
*
* Please note that code can not execute in flash while any part of the flash
* is being programmed or erased.
*
******************************************************************************/
extern void flash_disable_sectors_for_write(void);
#ifdef __cplusplus
}
#endif
#endif /* #ifndef OPENOCD_LOADERS_FLASH_CC26XX_FLASH_H */

View File

@ -0,0 +1,177 @@
/******************************************************************************
*
* Copyright (C) 2017-2018 Texas Instruments Incorporated - http://www.ti.com/
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* distribution.
*
* Neither the name of Texas Instruments Incorporated nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************/
#include <stdint.h>
#include <stdbool.h>
#include "flashloader.h"
#include "flash.h"
/* Array holding erased state of the flash sectors. */
static bool g_is_erased[FLASH_MAX_SECTOR_COUNT];
extern uint8_t g_retain_buf[];
uint32_t flashloader_init(struct flash_params *params, uint8_t *buf1,
uint8_t *buf2)
{
/* Initialize params buffers */
memset((void *)params, 0, 2 * sizeof(struct flash_params));
params[0].buf_addr = (uint32_t)buf1;
params[1].buf_addr = (uint32_t)buf2;
/* Mark all sectors at "not erased" */
memset(g_is_erased, false, sizeof(g_is_erased));
return STATUS_OK;
}
uint32_t flashloader_erase_and_program(uint8_t *src, uint32_t address,
uint32_t byte_count)
{
if (byte_count > BUFFER_LEN)
return STATUS_FAILED_INVALID_ARGUMENTS;
/* Erase affected sectors */
uint32_t status = flashloader_erase_sectors(address, byte_count);
if (status != STATUS_OK)
return status;
/* Program data */
status = flashloader_program(src, address, byte_count);
return status;
}
uint32_t flashloader_program_with_retain(uint8_t *src, uint32_t address,
uint32_t byte_count)
{
#if (BUFFER_LEN > FLASH_ERASE_SIZE)
#error Buffer size cannot be larger than the flash sector size!
#endif
uint32_t first_sector_idx;
uint32_t last_sector_idx;
uint32_t status = STATUS_OK;
uint32_t i;
first_sector_idx = flashloader_address_to_sector(address);
last_sector_idx = flashloader_address_to_sector(address + byte_count - 1);
/* Mark all sectors as "not erased" before starting */
memset(g_is_erased, false, sizeof(g_is_erased));
uint32_t sec_offset = address % FLASH_ERASE_SIZE;
uint32_t curr_count;
uint32_t src_offset = 0;
for (i = first_sector_idx; i <= last_sector_idx; i++) {
/* Chop off at sector boundary if data goes into the next sector. */
curr_count = byte_count;
if ((address + byte_count) > ((i+1) * FLASH_ERASE_SIZE))
curr_count -= (address + byte_count) % FLASH_ERASE_SIZE;
/* Copy flash sector to retain buffer */
memcpy(g_retain_buf, (void *)(i * FLASH_ERASE_SIZE), FLASH_ERASE_SIZE);
/* Copy data buffer to retain buffer */
memcpy(&g_retain_buf[sec_offset], &src[src_offset], curr_count);
/* Erase and program from retain buffer */
status = flashloader_erase_and_program(g_retain_buf,
(i * FLASH_ERASE_SIZE), FLASH_ERASE_SIZE);
if (status != STATUS_OK)
return status;
address += curr_count;
sec_offset = address % FLASH_ERASE_SIZE;
byte_count -= curr_count;
src_offset += curr_count;
}
return status;
}
uint32_t flashloader_erase_all(void)
{
if (flash_bank_erase(true) != FAPI_STATUS_SUCCESS)
return STATUS_FAILED_ERASE_ALL;
memset(g_is_erased, true, sizeof(g_is_erased));
return STATUS_OK;
}
uint32_t flashloader_erase_sectors(uint32_t address, uint32_t byte_count)
{
uint32_t first_sector_idx;
uint32_t last_sector_idx;
uint32_t status;
uint32_t idx;
/* Floor address to the start of the sector and convert to sector number */
first_sector_idx = flashloader_address_to_sector(address);
last_sector_idx = flashloader_address_to_sector(address + byte_count - 1);
/* Erase given sector(s) */
for (idx = first_sector_idx; idx <= last_sector_idx; idx++) {
/* Only erase sectors that haven't already been erased */
if (g_is_erased[idx] == false) {
status = flash_sector_erase(idx * FLASH_ERASE_SIZE);
if (status != FAPI_STATUS_SUCCESS) {
status = (STATUS_FAILED_SECTOR_ERASE |
((idx << STATUS_EXT_INFO_S) & STATUS_EXT_INFO_M) |
((status << STATUS_ROM_CODE_S) & STATUS_ROM_CODE_M));
return status;
}
g_is_erased[idx] = true;
}
}
return STATUS_OK;
}
uint32_t flashloader_program(uint8_t *src, uint32_t address,
uint32_t byte_count)
{
uint32_t status = flash_program(src, address, byte_count);
if (status != FAPI_STATUS_SUCCESS) {
status = (STATUS_FAILED_PROGRAM |
((status << STATUS_ROM_CODE_S) & STATUS_ROM_CODE_M));
}
return STATUS_OK;
}

View File

@ -0,0 +1,187 @@
/******************************************************************************
*
* Copyright (C) 2017-2018 Texas Instruments Incorporated - http://www.ti.com/
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* distribution.
*
* Neither the name of Texas Instruments Incorporated nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************/
#ifndef OPENOCD_LOADERS_FLASH_CC26XX_FLASHLOADER_H
#define OPENOCD_LOADERS_FLASH_CC26XX_FLASHLOADER_H
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include "flash.h"
/* Number of elements in an array */
#define NELEMS(a) (sizeof(a) / sizeof(a[0]))
struct __attribute__((__packed__)) flash_params {
uint32_t dest; /* Destination address in flash */
uint32_t len; /* Number of bytes */
uint32_t cmd; /* Command */
uint32_t full; /* Handshake signal. Is buffer ready? */
uint32_t buf_addr; /* Address of data buffer. */
};
typedef enum {
CMD_NO_ACTION = 0, /* No action, default value */
CMD_ERASE_ALL = 1, /* Erase all unprotected sectors */
CMD_PROGRAM = 2, /* Program data */
CMD_ERASE_AND_PROGRAM = 3, /* Erase and program data */
CMD_ERASE_AND_PROGRAM_WITH_RETAIN = 4, /* Erase and program, but retain */
/* sector data outside given range */
CMD_ERASE_SECTORS = 5 /* Erase unprotected sectors */
} flash_commands_t;
typedef enum {
BUFFER_EMPTY = 0x0, /* No data in buffer, flags last task complete */
BUFFER_FULL = 0xFFFFFFFF /* Buffer has data, flags next task to start */
} flash_handshake_t;
#define STATUS_FLASHLOADER_STATUS_M 0x0000FFFF
#define STATUS_FLASHLOADER_STATUS_S 0
#define STATUS_ROM_CODE_M 0x00FF0000
#define STATUS_ROM_CODE_S 16
#define STATUS_EXT_INFO_M 0xFF000000
#define STATUS_EXT_INFO_S 24
typedef enum {
STATUS_OK = 0,
STATUS_FAILED_ERASE_ALL = 0x101,
STATUS_FAILED_SECTOR_ERASE = 0x102,
STATUS_FAILED_PROGRAM = 0x103,
STATUS_FAILED_INVALID_ARGUMENTS = 0x104,
STATUS_FAILED_UNKNOWN_COMMAND = 0x105,
} flash_status_t;
/* The buffer size used by the flashloader. The size of 1 flash sector. */
#define BUFFER_LEN FLASH_ERASE_SIZE
/*
* This function initializes the flashloader. The application must
* allocate memory for the two data buffers and the flash_params structures.
*
* params Pointer an flash_params array with 2 elements.
* buf1 Pointer to data buffer 1
* buf2 Pointer to data buffer 2
*
* Returns STATUS_OK
*
*/
extern uint32_t flashloader_init(struct flash_params *params, uint8_t *buf1,
uint8_t *buf2);
/*
* Erase and program the necessary sectors. Data outside the given
* range will be deleted.
*
* src Pointer to buffer containing the data.
* address Start address in device flash
* byte_count The number of bytes to program
*
* Returns STATUS_OK on success. For status on failure:
* See flashloader_program() and flashloader_erase_sectors().
*
*/
extern uint32_t flashloader_erase_and_program(uint8_t *src, uint32_t address,
uint32_t byte_count);
/*
* Erase and program the device sectors. Data outside the given
* data range will be kept unchanged.
*
* src Pointer to buffer containing the data.
* address Start address in device flash
* byte_count The number of bytes to program
*
* Returns STATUS_OK on success. For status on failure:
* See flashloader_program() and flashloader_erase_sectors().
*
*/
extern uint32_t flashloader_program_with_retain(uint8_t *src, uint32_t address,
uint32_t byte_count);
/*
* Erases all flash sectors (that are not write-protected).
*
* Returns STATUS_OK on success.
*
*/
extern uint32_t flashloader_erase_all(void);
/*
* Erases the flash sectors affected by the given range.
*
* This function only erases sectors that are not already erased.
*
* start_addr The first address in the range.
* byte_count The number of bytes in the range.
*
* Returns STATUS_OK on success. Returns a combined status on failure:
* [31:24] The sector that failed.
* [23:16] ROM function status code. 0 means success.
* [16: 0] STATUS_FAILED_SECTOR_ERASE
*
*/
extern uint32_t flashloader_erase_sectors(uint32_t start_addr,
uint32_t byte_count);
/*
* Program the given range.
*
* This function does not erase anything, it assumes the sectors are ready to
* be programmed.
*
* src Pointer to buffer containing the data.
* address Start address in device flash
* byte_count The number of bytes to program
*
* Returns STATUS_OK on success. Returns a combined status value on failure:
* [31:16] ROM function status code. 0 means success.
* [15:0 ] STATUS_FAILED_PROGRAM
*
*/
extern uint32_t flashloader_program(uint8_t *src, uint32_t address,
uint32_t byte_count);
/*
* Convert the input address into a sector number.
*
* address The address.
*
* Returns the flash sector which the address resides in. The first sector
* is sector 0.
*
*/
static inline uint32_t flashloader_address_to_sector(uint32_t address)
{ return (address / FLASH_ERASE_SIZE); };
#endif /* #ifndef OPENOCD_LOADERS_FLASH_CC26XX_FLASHLOADER_H */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,179 @@
/******************************************************************************
*
* Copyright (C) 2017-2018 Texas Instruments Incorporated - http://www.ti.com/
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* distribution.
*
* Neither the name of Texas Instruments Incorporated nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************/
#include <stdint.h>
#include <stdbool.h>
#include "flashloader.h"
/* Data buffers used by host to communicate with flashloader */
/* Flashloader parameter structure. */
__attribute__ ((section(".buffers.g_cfg")))
volatile struct flash_params g_cfg[2];
/* Data buffer 1. */
__attribute__ ((section(".buffers.g_buf1")))
uint8_t g_buf1[BUFFER_LEN];
/* Data buffer 2. */
__attribute__ ((section(".buffers.g_buf2")))
uint8_t g_buf2[BUFFER_LEN];
/* Buffer used for program with retain feature */
__attribute__ ((section(".buffers.g_retain_buf")))
uint8_t g_retain_buf[BUFFER_LEN];
uint32_t g_curr_buf; /* Current buffer used. */
uint32_t g_vims_ctl; /* Saved flash cache state. */
/******************************************************************************
*
* This function stores the current VIMS configuration before
* - disabling VIMS flash cache
* - flushing the flash line buffers.
*
* Note Not using driverlib calls because it requires using "NO_ROM" define in
* order to work for both Cha. R1 and R2 using the same code. Manually
* doing the steps to minimize code footprint.
*
******************************************************************************/
static void disable_flash_cache()
{
/* 1. Make sure VIMS is not currently changing mode (VIMS:STAT register) */
while ((HWREG(0x40034000) & 0x00000008) == 0x8)
;
/* Save current VIMS:CTL state */
g_vims_ctl = HWREG(0x40034004);
/* 2. Set VIMS mode to OFF and disable flash line buffers */
uint32_t new_vims_ctl = g_vims_ctl | 0x33;
HWREG(0x40034004) = new_vims_ctl;
/* 3. Wait for VIMS to have changed mode (VIMS:STAT register) */
while ((HWREG(0x40034000) & 0x00000008) == 0x8)
;
}
/******************************************************************************
*
* This function restores the VIMS configuration saved off by
* disable_flash_cache().
*
* Note Not using driverlib calls because it requires using "NO_ROM" define in
* order to work for both Cha. R1 and R2 using the same code. Manually
* doing the steps to minimize code footprint.
*
******************************************************************************/
static void restore_cache_state()
{
HWREG(0x40034004) = g_vims_ctl;
/* Wait for VIMS to have changed mode (VIMS:STAT register) */
while ((HWREG(0x40034000) & 0x00000008) == 0x8)
;
}
/******************************************************************************
*
* CC13xx/CC26xx flashloader main function.
*
******************************************************************************/
int main(void)
{
flashloader_init((struct flash_params *)g_cfg, g_buf1, g_buf2);
g_curr_buf = 0; /* start with the first buffer */
uint32_t status;
while (1) {
/* Wait for host to signal buffer is ready */
while (g_cfg[g_curr_buf].full == BUFFER_EMPTY)
;
disable_flash_cache();
/* Perform requested task */
switch (g_cfg[g_curr_buf].cmd) {
case CMD_ERASE_ALL:
status = flashloader_erase_all();
break;
case CMD_PROGRAM:
status =
flashloader_program(
(uint8_t *)g_cfg[g_curr_buf].buf_addr,
g_cfg[g_curr_buf].dest, g_cfg[g_curr_buf].len);
break;
case CMD_ERASE_AND_PROGRAM:
status =
flashloader_erase_and_program(
(uint8_t *)g_cfg[g_curr_buf].buf_addr,
g_cfg[g_curr_buf].dest, g_cfg[g_curr_buf].len);
break;
case CMD_ERASE_AND_PROGRAM_WITH_RETAIN:
status =
flashloader_program_with_retain(
(uint8_t *)g_cfg[g_curr_buf].buf_addr,
g_cfg[g_curr_buf].dest, g_cfg[g_curr_buf].len);
break;
case CMD_ERASE_SECTORS:
status =
flashloader_erase_sectors(g_cfg[g_curr_buf].dest,
g_cfg[g_curr_buf].len);
break;
default:
status = STATUS_FAILED_UNKNOWN_COMMAND;
break;
}
restore_cache_state();
/* Enter infinite loop on error condition */
if (status != STATUS_OK) {
g_cfg[g_curr_buf].full = status;
while (1)
;
}
/* Mark current task complete, and begin looking at next buffer */
g_cfg[g_curr_buf].full = BUFFER_EMPTY;
g_curr_buf ^= 1;
}
}
void _exit(int status)
{
/* Enter infinite loop on hitting an exit condition */
(void)status; /* Unused parameter */
while (1)
;
}

View File

@ -0,0 +1,97 @@
/******************************************************************************
*
* Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com/
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* distribution.
*
* Neither the name of Texas Instruments Incorporated nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************/
#include <stdint.h>
/******************************************************************************
*
* The entry point for the application startup code.
*
******************************************************************************/
extern int main(void);
/******************************************************************************
*
* Reserve space for the system stack.
*
******************************************************************************/
__attribute__ ((section(".stack")))
static uint32_t stack[100];
const uint32_t stack_pntr = (uint32_t)stack + sizeof(stack);
/******************************************************************************
*
* The following are constructs created by the linker indicating where the
* the "bss" and "ebss" segments reside in memory.
*
******************************************************************************/
extern uint32_t _bss;
extern uint32_t _ebss;
/******************************************************************************
*
* This is the entry point that handles setting the stack within the allowed
* workspace, initializing the .bss segment, and then jumping to main.
*
******************************************************************************/
__attribute__ ((section(".entry")))
void entry(void)
{
/* Workaround for ITT instructions. */
__asm(" NOP");
__asm(" NOP");
__asm(" NOP");
__asm(" NOP");
/* Initialize stack pointer */
__asm(" ldr sp, =stack_pntr");
/* Zero fill the bss segment. */
__asm(" ldr r0, =_bss\n"
" ldr r1, =_ebss\n"
" mov r2, #0\n"
" .thumb_func\n"
" zero_loop:\n"
" cmp r0, r1\n"
" it lt\n"
" strlt r2, [r0], #4\n"
" blt zero_loop");
/* Call the application's entry point. */
main();
/* If we ever return, enter an infinite loop */
while (1)
;
}

View File

@ -0,0 +1,19 @@
BIN2C = ../../../../src/helper/bin2char.sh
CROSS_COMPILE ?= arm-none-eabi-
AS = $(CROSS_COMPILE)as
OBJCOPY = $(CROSS_COMPILE)objcopy
all: cc3220sf.inc
%.elf: %.s
$(AS) $< -o $@
%.bin: %.elf
$(OBJCOPY) -Obinary $< $@
%.inc: %.bin
$(BIN2C) < $< > $@
clean:
-rm -f *.elf *.bin *.inc

View File

@ -0,0 +1,10 @@
/* Autogenerated with ../../../../src/helper/bin2char.sh */
0xdf,0xf8,0x7c,0xa0,0xdf,0xf8,0x7c,0xb0,0xdf,0xf8,0x7c,0xc0,0x01,0xf0,0x7f,0x03,
0x00,0x2b,0x1e,0xd1,0x4f,0xf0,0x00,0x04,0xcc,0xf8,0x00,0x10,0x03,0x68,0xcb,0xf8,
0x00,0x30,0x0b,0xf1,0x04,0x0b,0x00,0xf1,0x04,0x00,0xa2,0xf1,0x01,0x02,0x04,0xf1,
0x01,0x04,0x01,0xf1,0x04,0x01,0x00,0x2a,0x01,0xd0,0x20,0x2c,0xee,0xd1,0xcc,0xf8,
0x20,0xa0,0xdc,0xf8,0x20,0x30,0x13,0xf0,0x01,0x0f,0xfa,0xd1,0x00,0x2a,0xd7,0xd1,
0x13,0xe0,0xcc,0xf8,0x00,0x10,0x03,0x68,0xcc,0xf8,0x04,0x30,0xcc,0xf8,0x08,0xa0,
0xdc,0xf8,0x08,0x30,0x13,0xf0,0x01,0x0f,0xfa,0xd1,0xa2,0xf1,0x01,0x02,0x00,0xf1,
0x04,0x00,0x01,0xf1,0x04,0x01,0x00,0x2a,0xc2,0xd1,0x00,0xbe,0x01,0xbe,0xfc,0xe7,
0x01,0x00,0x42,0xa4,0x00,0xd1,0x0f,0x40,0x00,0xd0,0x0f,0x40,

View File

@ -0,0 +1,93 @@
/***************************************************************************
* Copyright (C) 2017 by Texas Instruments, Inc. *
* *
* 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 2 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/>. *
***************************************************************************/
/* Params:
* r0 = buffer start address (in)
* r1 = flash destination address (in)
* r2 = number of words to write (in/out)
*/
.text
.cpu cortex-m4
.code 16
.thumb
.syntax unified
.align 2
/* r3 = scratchpad
* r4 = buffer word counter
* r10 = flash programming key
* r11 = base FWB address
* r12 = base flash regs address
*/
start:
ldr r10, =0xa4420001 /* flash programming key */
ldr r11, =0x400fd100 /* base of FWB */
ldr r12, =0x400fd000 /* base of flash regs */
and r3, r1, #0x7f /* is the dest address 32 word aligned? */
cmp r3, #0
bne program_word /* if not aligned do one word at a time */
/* program using the write buffers */
program_buffer:
mov r4, #0 /* start the buffer word counter at 0 */
str r1, [r12] /* store the dest addr in FMA */
fill_buffer:
ldr r3, [r0] /* get the word to write to FWB */
str r3, [r11] /* store the word in the FWB */
add r11, r11, #4 /* increment the FWB pointer */
add r0, r0, #4 /* increment the source pointer */
sub r2, r2, #1 /* decrement the total word counter */
add r4, r4, #1 /* increment the buffer word counter */
add r1, r1, #4 /* increment the dest pointer */
cmp r2, #0 /* is the total word counter now 0? */
beq buffer_ready /* go to end if total word counter is 0 */
cmp r4, #32 /* is the buffer word counter now 32? */
bne fill_buffer /* go to continue to fill buffer */
buffer_ready:
str r10, [r12, #0x20] /* store the key and write bit to FMC2 */
wait_buffer_done:
ldr r3, [r12, #0x20] /* read FMC2 */
tst r3, #1 /* see if the write bit is cleared */
bne wait_buffer_done /* go to read FMC2 if bit not cleared */
cmp r2, #0 /* is the total word counter now 0? */
bne start /* go if there is more to program */
b exit
/* program just one word */
program_word:
str r1, [r12] /* store the dest addr in FMA */
ldr r3, [r0] /* get the word to write to FMD */
str r3, [r12, #0x4] /* store the word in FMD */
str r10, [r12, #0x8] /* store the key and write bit to FMC */
wait_word_done:
ldr r3, [r12, #0x8] /* read FMC */
tst r3, #1 /* see if the write bit is cleared */
bne wait_word_done /* go to read FMC if bit not cleared */
sub r2, r2, #1 /* decrement the total word counter */
add r0, r0, #4 /* increment the source pointer */
add r1, r1, #4 /* increment the dest pointer */
cmp r2, #0 /* is the total word counter now 0 */
bne start /* go if there is more to program */
/* end */
exit:
bkpt #0
bkpt #1
b exit

View File

@ -0,0 +1,126 @@
/******************************************************************************
*
* Copyright (C) 2014-2018 Texas Instruments Incorporated - http://www.ti.com/
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* distribution.
*
* Neither the name of Texas Instruments Incorporated nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************/
#ifndef OPENOCD_LOADERS_FLASH_MSP432_MSP432E4_FLASHLIBIF_H
#define OPENOCD_LOADERS_FLASH_MSP432_MSP432E4_FLASHLIBIF_H
#include <stddef.h>
#include <stdint.h>
/* RAM loader */
static const uint32_t RAM_LOADER_START = 0x20000000u; /* Code space */
static const uint32_t RAM_LOADER_MAIN = 0x20000110u; /* Code space */
static const uint32_t RAM_LOADER_BUFFER1 = 0x20002000u; /* SBUS data space */
static const uint32_t RAM_LOADER_BUFFER2 = 0x20003000u; /* SBUS data space */
static const uint32_t RAM_LOADER_STACK = 0x20002000u; /* SBUS data space */
/* Address for flash function to be executed */
static const uint32_t FLASH_FUNCTION_ADDRESS = 0x20000150u;
enum flash_command {
FLASH_NO_COMMAND = 0,
FLASH_MASS_ERASE = 1,
FLASH_SECTOR_ERASE = 2,
FLASH_PROGRAM = 4,
FLASH_INIT = 8,
FLASH_EXIT = 16,
FLASH_CONTINUOUS_PROGRAM = 32
};
/* Address for algorithm program and flash buffer */
static const uint32_t DST_ADDRESS = 0x2000015Cu;
static const uint32_t SRC_LENGTH_ADDRESS = 0x20000160u;
static const uint32_t BUFFER1_STATUS_REGISTER = 0x20000164u;
static const uint32_t BUFFER2_STATUS_REGISTER = 0x20000168u;
static const uint32_t BUFFER_INACTIVE = 0x00000000u;
static const uint32_t BUFFER_ACTIVE = 0x00000001u;
static const uint32_t BUFFER_DATA_READY = 0x00000010u;
static const size_t SRC_LENGTH_MAX = 4096u;
/* Erase options */
static const uint32_t ERASE_PARAM_ADDRESS = 0x2000016Cu;
static const uint32_t ERASE_MAIN = 0x00000001u;
static const uint32_t ERASE_INFO = 0x00000002u;
/* Unlock BSL */
static const uint32_t UNLOCK_BSL_ADDRESS = 0x20000170u;
static const uint32_t LOCK_BSL_KEY = 0x00000000u;
static const uint32_t UNLOCK_BSL_KEY = 0x0000000Bu;
/* Address for return code */
static const uint32_t RETURN_CODE_ADDRESS = 0x20000154u;
/* Return codes */
static const uint32_t FLASH_BUSY = 0x00000001u;
static const uint32_t FLASH_SUCCESS = 0x00000ACEu;
static const uint32_t FLASH_ERROR = 0x0000DEADu;
static const uint32_t FLASH_TIMEOUT_ERROR = 0xDEAD0000u;
static const uint32_t FLASH_VERIFY_ERROR = 0xDEADDEADu;
static const uint32_t FLASH_WRONG_COMMAND = 0x00000BADu;
static const uint32_t FLASH_POWER_ERROR = 0x00DEAD00u;
/* Device ID address */
static const uint32_t DEVICE_ID_ADDRESS = 0x0020100Cu;
static const uint32_t PC_REGISTER = 15u;
static const uint32_t SP_REGISTER = 13u;
/* CS silicon and boot code revisions */
static const uint32_t SILICON_REV_ADDRESS = 0x00201010u;
static const uint32_t SILICON_REV_A = 0x00000041u;
static const uint32_t SILICON_REV_B = 0x00000042u;
static const uint32_t SILICON_REV_C = 0x00000043u;
static const uint32_t SILICON_REV_D = 0x00000044u;
static const uint32_t SILICON_REV_E = 0x00000045u;
static const uint32_t SILICON_REV_F = 0x00000046u;
static const uint32_t SILICON_REV_G = 0x00000047u;
static const uint32_t SILICON_REV_H = 0x00000048u;
static const uint32_t SILICON_REV_I = 0x00000049u;
static const uint32_t SILICON_REV_B_WRONG = 0x00004100u;
struct flash_interface {
volatile uint32_t FLASH_FUNCTION;
volatile uint32_t RETURN_CODE;
volatile uint32_t _RESERVED0;
volatile uint32_t DST_ADDRESS;
volatile uint32_t SRC_LENGTH;
volatile uint32_t BUFFER1_STATUS_REGISTER;
volatile uint32_t BUFFER2_STATUS_REGISTER;
volatile uint32_t ERASE_PARAM;
volatile uint32_t UNLOCK_BSL;
};
#define FLASH_LOADER_BASE ((uint32_t)0x20000150u)
#define FLASH_LOADER ((struct flash_interface *) FLASH_LOADER_BASE)
#endif /* OPENOCD_LOADERS_FLASH_MSP432_MSP432E4_FLASHLIBIF_H */

View File

@ -0,0 +1,126 @@
/******************************************************************************
*
* Copyright (C) 2014-2018 Texas Instruments Incorporated - http://www.ti.com/
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* distribution.
*
* Neither the name of Texas Instruments Incorporated nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************/
#ifndef OPENOCD_LOADERS_FLASH_MSP432_MSP432P4_FLASHLIBIF_H
#define OPENOCD_LOADERS_FLASH_MSP432_MSP432P4_FLASHLIBIF_H
#include <stddef.h>
#include <stdint.h>
/* RAM loader */
static const uint32_t RAM_LOADER_START = 0x01000000u; /* Code space */
static const uint32_t RAM_LOADER_MAIN = 0x01000110u; /* Code space */
static const uint32_t RAM_LOADER_BUFFER1 = 0x20002000u; /* SBUS data space */
static const uint32_t RAM_LOADER_BUFFER2 = 0x20003000u; /* SBUS data space */
static const uint32_t RAM_LOADER_STACK = 0x20002000u; /* SBUS data space */
/* Address for flash function to be executed */
static const uint32_t FLASH_FUNCTION_ADDRESS = 0x20000150u;
enum flash_command {
FLASH_NO_COMMAND = 0,
FLASH_MASS_ERASE = 1,
FLASH_SECTOR_ERASE = 2,
FLASH_PROGRAM = 4,
FLASH_INIT = 8,
FLASH_EXIT = 16,
FLASH_CONTINUOUS_PROGRAM = 32
};
/* Address for algorithm program and flash buffer */
static const uint32_t DST_ADDRESS = 0x2000015Cu;
static const uint32_t SRC_LENGTH_ADDRESS = 0x20000160u;
static const uint32_t BUFFER1_STATUS_REGISTER = 0x20000164u;
static const uint32_t BUFFER2_STATUS_REGISTER = 0x20000168u;
static const uint32_t BUFFER_INACTIVE = 0x00000000u;
static const uint32_t BUFFER_ACTIVE = 0x00000001u;
static const uint32_t BUFFER_DATA_READY = 0x00000010u;
static const size_t SRC_LENGTH_MAX = 4096u;
/* erase options */
static const uint32_t ERASE_PARAM_ADDRESS = 0x2000016Cu;
static const uint32_t ERASE_MAIN = 0x00000001u;
static const uint32_t ERASE_INFO = 0x00000002u;
/* Unlock BSL */
static const uint32_t UNLOCK_BSL_ADDRESS = 0x20000170u;
static const uint32_t LOCK_BSL_KEY = 0x00000000u;
static const uint32_t UNLOCK_BSL_KEY = 0x0000000Bu;
/* Address for return code */
static const uint32_t RETURN_CODE_ADDRESS = 0x20000154u;
/* Return codes */
static const uint32_t FLASH_BUSY = 0x00000001u;
static const uint32_t FLASH_SUCCESS = 0x00000ACEu;
static const uint32_t FLASH_ERROR = 0x0000DEADu;
static const uint32_t FLASH_TIMEOUT_ERROR = 0xDEAD0000u;
static const uint32_t FLASH_VERIFY_ERROR = 0xDEADDEADu;
static const uint32_t FLASH_WRONG_COMMAND = 0x00000BADu;
static const uint32_t FLASH_POWER_ERROR = 0x00DEAD00u;
/* Device ID address */
static const uint32_t DEVICE_ID_ADDRESS = 0x0020100Cu;
static const uint32_t PC_REGISTER = 15u;
static const uint32_t SP_REGISTER = 13u;
/* CS silicon and boot code revisions */
static const uint32_t SILICON_REV_ADDRESS = 0x00201010u;
static const uint32_t SILICON_REV_A = 0x00000041u;
static const uint32_t SILICON_REV_B = 0x00000042u;
static const uint32_t SILICON_REV_C = 0x00000043u;
static const uint32_t SILICON_REV_D = 0x00000044u;
static const uint32_t SILICON_REV_E = 0x00000045u;
static const uint32_t SILICON_REV_F = 0x00000046u;
static const uint32_t SILICON_REV_G = 0x00000047u;
static const uint32_t SILICON_REV_H = 0x00000048u;
static const uint32_t SILICON_REV_I = 0x00000049u;
static const uint32_t SILICON_REV_B_WRONG = 0x00004100u;
struct flash_interface {
volatile uint32_t FLASH_FUNCTION;
volatile uint32_t RETURN_CODE;
volatile uint32_t _RESERVED0;
volatile uint32_t DST_ADDRESS;
volatile uint32_t SRC_LENGTH;
volatile uint32_t BUFFER1_STATUS_REGISTER;
volatile uint32_t BUFFER2_STATUS_REGISTER;
volatile uint32_t ERASE_PARAM;
volatile uint32_t UNLOCK_BSL;
};
#define FLASH_LOADER_BASE ((uint32_t)0x20000150u)
#define FLASH_LOADER ((struct flash_interface *) FLASH_LOADER_BASE)
#endif /* OPENOCD_LOADERS_FLASH_MSP432_MSP432P4_FLASHLIBIF_H */

View File

@ -0,0 +1,99 @@
BIN2C = ../../../../src/helper/bin2char.sh
CROSS_COMPILE ?= arm-none-eabi-
GCC = $(CROSS_COMPILE)gcc
OBJCOPY = $(CROSS_COMPILE)objcopy
FLAGS = -mcpu=cortex-m4 -march=armv7e-m -mfloat-abi=hard -mfpu=fpv4-sp-d16 -mthumb
CFLAGS = -c -DNO_MSP_CLASSIC_DEFINES -Dgcc -Wall -ffunction-sections
CFLAGS += -fdata-sections -std=c99 -O4
LDFLAGS = -lc -lnosys -Wl,--gc-sections
MSP432E4X_OBJS := \
msp432e4x/driverlib.o \
msp432e4x/main_msp432e4x.o \
msp432e4x/startup_msp432e4.o
MSP432P401X_OBJS := \
msp432p401x/driverlib.o \
msp432p401x/main_msp432p401x.o \
msp432p401x/startup_msp432p4.o
MSP432P411X_OBJS := \
msp432p411x/driverlib.o \
msp432p411x/main_msp432p411x.o \
msp432p411x/startup_msp432p4.o
all: msp432e4x_algo.inc msp432p401x_algo.inc msp432p411x_algo.inc
msp432e4x/%.o: %.c
@echo 'Building file: $<'
@echo 'Invoking: GNU Compiler'
$(GCC) -D__MSP432E4X__ $(FLAGS) $(CFLAGS) -o"$@" "$(shell echo $<)"
@echo 'Finished building: $<'
@echo ' '
msp432p401x/%.o: %.c
@echo 'Building file: $<'
@echo 'Invoking: GNU Compiler'
$(GCC) -D__MSP432P401X__ $(FLAGS) $(CFLAGS) -o"$@" "$(shell echo $<)"
@echo 'Finished building: $<'
@echo ' '
msp432p411x/%.o: %.c
@echo 'Building file: $<'
@echo 'Invoking: GNU Compiler'
$(GCC) -D__MSP432P411X__ $(FLAGS) $(CFLAGS) -o"$@" "$(shell echo $<)"
@echo 'Finished building: $<'
@echo ' '
msp432e4x_algo.out: $(MSP432E4X_OBJS)
@echo 'Building target: $@'
@echo 'Invoking: GNU Linker'
$(GCC) $(FLAGS) $(LDFLAGS) -o$@ $(MSP432E4X_OBJS) -Tmsp432e4x/msp432e4x.lds
@echo 'Finished building target: $@'
@echo ' '
msp432p401x_algo.out: $(MSP432P401X_OBJS)
@echo 'Building target: $@'
@echo 'Invoking: GNU Linker'
$(GCC) $(FLAGS) $(LDFLAGS) -o$@ $(MSP432P401X_OBJS) -Tmsp432p401x/msp432p401x.lds
@echo 'Finished building target: $@'
@echo ' '
msp432p411x_algo.out: $(MSP432P411X_OBJS)
@echo 'Building target: $@'
@echo 'Invoking: GNU Linker'
$(GCC) $(FLAGS) $(LDFLAGS) -o$@ $(MSP432P411X_OBJS) -Tmsp432p411x/msp432p411x.lds
@echo 'Finished building target: $@'
@echo ' '
%.bin: %.out
@echo 'Building target: $@'
@echo 'Invoking: GNU Objcopy Utility'
$(OBJCOPY) -Obinary $< $@
@echo 'Finished building target: $@'
@echo ' '
%.inc: %.bin
@echo 'Building target: $@'
@echo 'Invoking Bin2Char Script'
$(BIN2C) < $< > $@
rm $< $*.out
@echo 'Finished building target: $@'
@echo ' '
clean:
@echo 'Cleaning Targets and Build Artifacts'
rm -rf *.inc *.bin *.out *.map
rm -rf msp432e4x/*.o msp432e4x/*.d
rm -rf msp432p401x/*.o msp432p401x/*.d
rm -rf msp432p411x/*.o msp432p411x/*.d
@echo 'Finished clean'
@echo ' '
.PRECIOUS: %.bin
.PHONY: all clean

View File

@ -0,0 +1,472 @@
/******************************************************************************
*
* Copyright (C) 2017-2018 Texas Instruments Incorporated - http://www.ti.com/
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* distribution.
*
* Neither the name of Texas Instruments Incorporated nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************/
#include <stdint.h>
#include <stdbool.h>
#include "driverlib.h"
/*
* Wrapper function for the CPSID instruction.
* Returns the state of PRIMASK on entry.
*/
uint32_t __attribute__((naked)) cpu_cpsid(void)
{
uint32_t ret;
/* Read PRIMASK and disable interrupts. */
__asm(" mrs r0, PRIMASK\n"
" cpsid i\n"
" bx lr\n"
: "=r" (ret));
/*
* The return is handled in the inline assembly, but the compiler will
* still complain if there is not an explicit return here (despite the fact
* that this does not result in any code being produced because of the
* naked attribute).
*/
return ret;
}
/* Wrapper function for the CPUWFI instruction. */
void __attribute__((naked)) cpu_wfi(void)
{
/* Wait for the next interrupt. */
__asm(" wfi\n"
" bx lr\n");
}
/* Power Control Module APIs */
#if defined(PCM)
static bool __pcm_set_core_voltage_level_advanced(uint_fast8_t voltage_level,
uint32_t time_out, bool blocking)
{
uint8_t power_mode;
uint8_t current_voltage_level;
uint32_t reg_value;
bool bool_timeout;
/* Getting current power mode and level */
power_mode = pcm_get_power_mode();
current_voltage_level = pcm_get_core_voltage_level();
bool_timeout = time_out > 0 ? true : false;
/* If we are already at the power mode they requested, return */
if (current_voltage_level == voltage_level)
return true;
while (current_voltage_level != voltage_level) {
reg_value = PCM->CTL0;
switch (pcm_get_power_state()) {
case PCM_AM_LF_VCORE1:
case PCM_AM_DCDC_VCORE1:
case PCM_AM_LDO_VCORE0:
PCM->CTL0 = (PCM_KEY | (PCM_AM_LDO_VCORE1)
| (reg_value & ~(PCM_CTL0_KEY_MASK | PCM_CTL0_AMR_MASK)));
break;
case PCM_AM_LF_VCORE0:
case PCM_AM_DCDC_VCORE0:
case PCM_AM_LDO_VCORE1:
PCM->CTL0 = (PCM_KEY | (PCM_AM_LDO_VCORE0)
| (reg_value & ~(PCM_CTL0_KEY_MASK | PCM_CTL0_AMR_MASK)));
break;
default:
break;
}
if (blocking) {
while (BITBAND_PERI(PCM->CTL1, PCM_CTL1_PMR_BUSY_OFS)) {
if (bool_timeout && !(--time_out))
return false;
}
} else
return true;
current_voltage_level = pcm_get_core_voltage_level();
}
/* Changing the power mode if we are stuck in LDO mode */
if (power_mode != pcm_get_power_mode()) {
if (power_mode == PCM_DCDC_MODE)
return pcm_set_power_mode(PCM_DCDC_MODE);
else
return pcm_set_power_mode(PCM_LF_MODE);
}
return true;
}
bool pcm_set_core_voltage_level(uint_fast8_t voltage_level)
{
return __pcm_set_core_voltage_level_advanced(voltage_level, 0, true);
}
uint8_t pcm_get_power_mode(void)
{
uint8_t current_power_state;
current_power_state = pcm_get_power_state();
switch (current_power_state) {
case PCM_AM_LDO_VCORE0:
case PCM_AM_LDO_VCORE1:
case PCM_LPM0_LDO_VCORE0:
case PCM_LPM0_LDO_VCORE1:
default:
return PCM_LDO_MODE;
case PCM_AM_DCDC_VCORE0:
case PCM_AM_DCDC_VCORE1:
case PCM_LPM0_DCDC_VCORE0:
case PCM_LPM0_DCDC_VCORE1:
return PCM_DCDC_MODE;
case PCM_LPM0_LF_VCORE0:
case PCM_LPM0_LF_VCORE1:
case PCM_AM_LF_VCORE1:
case PCM_AM_LF_VCORE0:
return PCM_LF_MODE;
}
}
uint8_t pcm_get_core_voltage_level(void)
{
uint8_t current_power_state = pcm_get_power_state();
switch (current_power_state) {
case PCM_AM_LDO_VCORE0:
case PCM_AM_DCDC_VCORE0:
case PCM_AM_LF_VCORE0:
case PCM_LPM0_LDO_VCORE0:
case PCM_LPM0_DCDC_VCORE0:
case PCM_LPM0_LF_VCORE0:
default:
return PCM_VCORE0;
case PCM_AM_LDO_VCORE1:
case PCM_AM_DCDC_VCORE1:
case PCM_AM_LF_VCORE1:
case PCM_LPM0_LDO_VCORE1:
case PCM_LPM0_DCDC_VCORE1:
case PCM_LPM0_LF_VCORE1:
return PCM_VCORE1;
case PCM_LPM3:
return PCM_VCORELPM3;
}
}
static bool __pcm_set_power_mode_advanced(uint_fast8_t power_mode,
uint32_t time_out, bool blocking)
{
uint8_t current_power_mode;
uint8_t current_power_state;
uint32_t reg_value;
bool bool_timeout;
/* Getting Current Power Mode */
current_power_mode = pcm_get_power_mode();
/* If the power mode being set it the same as the current mode, return */
if (power_mode == current_power_mode)
return true;
current_power_state = pcm_get_power_state();
bool_timeout = time_out > 0 ? true : false;
/* Go through the while loop while we haven't achieved the power mode */
while (current_power_mode != power_mode) {
reg_value = PCM->CTL0;
switch (current_power_state) {
case PCM_AM_DCDC_VCORE0:
case PCM_AM_LF_VCORE0:
PCM->CTL0 = (PCM_KEY | PCM_AM_LDO_VCORE0
| (reg_value & ~(PCM_CTL0_KEY_MASK | PCM_CTL0_AMR_MASK)));
break;
case PCM_AM_LF_VCORE1:
case PCM_AM_DCDC_VCORE1:
PCM->CTL0 = (PCM_KEY | PCM_AM_LDO_VCORE1
| (reg_value & ~(PCM_CTL0_KEY_MASK | PCM_CTL0_AMR_MASK)));
break;
case PCM_AM_LDO_VCORE1: {
if (power_mode == PCM_DCDC_MODE) {
PCM->CTL0 = (PCM_KEY | PCM_AM_DCDC_VCORE1
| (reg_value & ~(PCM_CTL0_KEY_MASK
| PCM_CTL0_AMR_MASK)));
} else if (power_mode == PCM_LF_MODE) {
PCM->CTL0 = (PCM_KEY | PCM_AM_LF_VCORE1
| (reg_value & ~(PCM_CTL0_KEY_MASK
| PCM_CTL0_AMR_MASK)));
} else
return false;
break;
}
case PCM_AM_LDO_VCORE0: {
if (power_mode == PCM_DCDC_MODE) {
PCM->CTL0 = (PCM_KEY | PCM_AM_DCDC_VCORE0
| (reg_value & ~(PCM_CTL0_KEY_MASK
| PCM_CTL0_AMR_MASK)));
} else if (power_mode == PCM_LF_MODE) {
PCM->CTL0 = (PCM_KEY | PCM_AM_LF_VCORE0
| (reg_value & ~(PCM_CTL0_KEY_MASK
| PCM_CTL0_AMR_MASK)));
} else
return false;
break;
}
default:
break;
}
if (blocking) {
while (BITBAND_PERI(PCM->CTL1, PCM_CTL1_PMR_BUSY_OFS)) {
if (bool_timeout && !(--time_out))
return false;
}
} else
return true;
current_power_mode = pcm_get_power_mode();
current_power_state = pcm_get_power_state();
}
return true;
}
bool pcm_set_power_mode(uint_fast8_t power_mode)
{
return __pcm_set_power_mode_advanced(power_mode, 0, true);
}
static bool __pcm_set_power_state_advanced(uint_fast8_t power_state,
uint32_t timeout, bool blocking)
{
uint8_t current_power_state;
current_power_state = pcm_get_power_state();
if (current_power_state == power_state)
return true;
switch (power_state) {
case PCM_AM_LDO_VCORE0:
return __pcm_set_core_voltage_level_advanced(PCM_VCORE0, timeout,
blocking) && __pcm_set_power_mode_advanced(PCM_LDO_MODE,
timeout, blocking);
case PCM_AM_LDO_VCORE1:
return __pcm_set_core_voltage_level_advanced(PCM_VCORE1, timeout,
blocking) && __pcm_set_power_mode_advanced(PCM_LDO_MODE,
timeout, blocking);
case PCM_AM_DCDC_VCORE0:
return __pcm_set_core_voltage_level_advanced(PCM_VCORE0, timeout,
blocking) && __pcm_set_power_mode_advanced(PCM_DCDC_MODE,
timeout, blocking);
case PCM_AM_DCDC_VCORE1:
return __pcm_set_core_voltage_level_advanced(PCM_VCORE1, timeout,
blocking) && __pcm_set_power_mode_advanced(PCM_DCDC_MODE,
timeout, blocking);
case PCM_AM_LF_VCORE0:
return __pcm_set_core_voltage_level_advanced(PCM_VCORE0, timeout,
blocking) && __pcm_set_power_mode_advanced(PCM_LF_MODE,
timeout, blocking);
case PCM_AM_LF_VCORE1:
return __pcm_set_core_voltage_level_advanced(PCM_VCORE1, timeout,
blocking) && __pcm_set_power_mode_advanced(PCM_LF_MODE,
timeout, blocking);
case PCM_LPM0_LDO_VCORE0:
if (!__pcm_set_core_voltage_level_advanced(PCM_VCORE0, timeout,
blocking) || !__pcm_set_power_mode_advanced(PCM_LDO_MODE,
timeout, blocking))
break;
return pcm_goto_lpm0();
case PCM_LPM0_LDO_VCORE1:
if (!__pcm_set_core_voltage_level_advanced(PCM_VCORE1, timeout,
blocking) || !__pcm_set_power_mode_advanced(PCM_LDO_MODE,
timeout, blocking))
break;
return pcm_goto_lpm0();
case PCM_LPM0_DCDC_VCORE0:
if (!__pcm_set_core_voltage_level_advanced(PCM_VCORE0, timeout,
blocking) || !__pcm_set_power_mode_advanced(PCM_DCDC_MODE,
timeout, blocking))
break;
return pcm_goto_lpm0();
case PCM_LPM0_DCDC_VCORE1:
if (!__pcm_set_core_voltage_level_advanced(PCM_VCORE1, timeout,
blocking) || !__pcm_set_power_mode_advanced(PCM_DCDC_MODE,
timeout, blocking))
break;
return pcm_goto_lpm0();
case PCM_LPM0_LF_VCORE0:
if (!__pcm_set_core_voltage_level_advanced(PCM_VCORE0, timeout,
blocking) || !__pcm_set_power_mode_advanced(PCM_LF_MODE,
timeout, blocking))
break;
return pcm_goto_lpm0();
case PCM_LPM0_LF_VCORE1:
if (!__pcm_set_core_voltage_level_advanced(PCM_VCORE1, timeout,
blocking) || !__pcm_set_power_mode_advanced(PCM_LF_MODE,
timeout, blocking))
break;
return pcm_goto_lpm0();
case PCM_LPM3:
return pcm_goto_lpm3();
case PCM_LPM4:
return pcm_goto_lpm4();
case PCM_LPM45:
return pcm_shutdown_device(PCM_LPM45);
case PCM_LPM35_VCORE0:
return pcm_shutdown_device(PCM_LPM35_VCORE0);
default:
return false;
}
return false;
}
bool pcm_set_power_state(uint_fast8_t power_state)
{
return __pcm_set_power_state_advanced(power_state, 0, true);
}
bool pcm_shutdown_device(uint32_t shutdown_mode)
{
uint32_t shutdown_mode_bits = (shutdown_mode == PCM_LPM45) ?
PCM_CTL0_LPMR_12 : PCM_CTL0_LPMR_10;
/* If a power transition is occuring, return false */
if (BITBAND_PERI(PCM->CTL1, PCM_CTL1_PMR_BUSY_OFS))
return false;
/* Initiating the shutdown */
SCB->SCR |= SCB_SCR_SLEEPDEEP_MSK;
PCM->CTL0 = (PCM_KEY | shutdown_mode_bits
| (PCM->CTL0 & ~(PCM_CTL0_KEY_MASK | PCM_CTL0_LPMR_MASK)));
cpu_wfi();
return true;
}
bool pcm_goto_lpm4(void)
{
/* Disabling RTC_C and WDT_A */
wdt_a_hold_timer();
rtc_c_hold_clock();
/* LPM4 is just LPM3 with WDT_A/RTC_C disabled... */
return pcm_goto_lpm3();
}
bool pcm_goto_lpm0(void)
{
/* If we are in the middle of a state transition, return false */
if (BITBAND_PERI(PCM->CTL1, PCM_CTL1_PMR_BUSY_OFS))
return false;
SCB->SCR &= ~SCB_SCR_SLEEPDEEP_MSK;
cpu_wfi();
return true;
}
bool pcm_goto_lpm3(void)
{
uint_fast8_t current_power_state;
uint_fast8_t current_power_mode;
/* If we are in the middle of a state transition, return false */
if (BITBAND_PERI(PCM->CTL1, PCM_CTL1_PMR_BUSY_OFS))
return false;
/* If we are in the middle of a shutdown, return false */
if ((PCM->CTL0 & PCM_CTL0_LPMR_MASK) == PCM_CTL0_LPMR_10
|| (PCM->CTL0 & PCM_CTL0_LPMR_MASK) == PCM_CTL0_LPMR_12)
return false;
current_power_mode = pcm_get_power_mode();
current_power_state = pcm_get_power_state();
if (current_power_mode == PCM_DCDC_MODE)
pcm_set_power_mode(PCM_LDO_MODE);
/* Clearing the SDR */
PCM->CTL0 =
(PCM->CTL0 & ~(PCM_CTL0_KEY_MASK | PCM_CTL0_LPMR_MASK)) | PCM_KEY;
/* Setting the sleep deep bit */
SCB->SCR |= SCB_SCR_SLEEPDEEP_MSK;
cpu_wfi();
SCB->SCR &= ~SCB_SCR_SLEEPDEEP_MSK;
return pcm_set_power_state(current_power_state);
}
uint8_t pcm_get_power_state(void)
{
return (PCM->CTL0 & PCM_CTL0_CPM_MASK) >> PCM_CTL0_CPM_OFS;
}
#endif
/* Real Time Clock APIs */
#if defined(RTC_C)
void rtc_c_hold_clock(void)
{
RTC_C->CTL0 = (RTC_C->CTL0 & ~RTC_C_CTL0_KEY_MASK) | RTC_C_KEY;
BITBAND_PERI(RTC_C->CTL13, RTC_C_CTL13_HOLD_OFS) = 1;
BITBAND_PERI(RTC_C->CTL0, RTC_C_CTL0_KEY_OFS) = 0;
}
#endif
/* Watch Dog Timer APIs */
#if defined(WDT_A)
void wdt_a_hold_timer(void)
{
/* Set Hold bit */
uint8_t new_wdt_status = (WDT_A->CTL | WDT_A_CTL_HOLD);
WDT_A->CTL = WDT_A_CTL_PW + new_wdt_status;
}
#endif

View File

@ -0,0 +1,384 @@
/******************************************************************************
*
* Copyright (C) 2017-2018 Texas Instruments Incorporated - http://www.ti.com/
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* distribution.
*
* Neither the name of Texas Instruments Incorporated nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************/
#ifndef OPENOCD_LOADERS_FLASH_MSP432_DRIVERLIB_H
#define OPENOCD_LOADERS_FLASH_MSP432_DRIVERLIB_H
#include <stdint.h>
#include <stdbool.h>
#ifdef __cplusplus
extern "C" {
#endif
#if defined(__MSP432E4X__)
#include "msp432e4x.h"
#elif defined(__MSP432P401X__)
#include "msp432p401x.h"
#elif defined(__MSP432P411X__)
#include "msp432p411x.h"
#else
#error "Failed to match a device specific include file"
#endif
/* Structure type to access the System Control Block (SCB). */
struct SCB_Type {
volatile uint32_t CPUID; /* CPUID Base Register */
volatile uint32_t ICSR; /* Interrupt Control and State Register */
volatile uint32_t VTOR; /* Vector Table Offset Register */
volatile uint32_t AIRCR; /* Application Interrupt and Reset Control */
volatile uint32_t SCR; /* System Control Register */
volatile uint32_t CCR; /* Configuration Control Register */
volatile uint8_t SHP[12U]; /* System Handlers Priority Registers */
volatile uint32_t SHCSR; /* System Handler Control and State */
volatile uint32_t CFSR; /* Configurable Fault Status Register */
volatile uint32_t HFSR; /* HardFault Status Register */
volatile uint32_t DFSR; /* Debug Fault Status Register */
volatile uint32_t MMFAR; /* MemManage Fault Address Register */
volatile uint32_t BFAR; /* BusFault Address Register */
volatile uint32_t AFSR; /* Auxiliary Fault Status Register */
volatile uint32_t PFR[2U]; /* Processor Feature Register */
volatile uint32_t DFR; /* Debug Feature Register */
volatile uint32_t ADR; /* Auxiliary Feature Register */
volatile uint32_t MMFR[4U]; /* Memory Model Feature Register */
volatile uint32_t ISAR[5U]; /* Instruction Set Attributes Register */
uint32_t RESERVED0[5U];
volatile uint32_t CPACR; /* Coprocessor Access Control Register */
};
/* SCB:SCR register bits */
#define SCB_SCR_SLEEPDEEP_POS 2U
#define SCB_SCR_SLEEPDEEP_MSK (1UL << SCB_SCR_SLEEPDEEP_POS)
/* Memory mapping of Core Hardware */
#define SCS_BASE (0xE000E000UL) /* System Control Space Base Address */
#define SCB_BASE (SCS_BASE + 0x0D00UL) /* System Control Block Base Address */
#define SCB ((struct SCB_Type *)SCB_BASE) /* SCB configuration struct */
/* Definitions of standard bits */
#define BIT0 (uint16_t)(0x0001)
#define BIT1 (uint16_t)(0x0002)
#define BIT2 (uint16_t)(0x0004)
#define BIT3 (uint16_t)(0x0008)
#define BIT4 (uint16_t)(0x0010)
#define BIT5 (uint16_t)(0x0020)
#define BIT6 (uint16_t)(0x0040)
#define BIT7 (uint16_t)(0x0080)
#define BIT8 (uint16_t)(0x0100)
#define BIT9 (uint16_t)(0x0200)
#define BITA (uint16_t)(0x0400)
#define BITB (uint16_t)(0x0800)
#define BITC (uint16_t)(0x1000)
#define BITD (uint16_t)(0x2000)
#define BITE (uint16_t)(0x4000)
#define BITF (uint16_t)(0x8000)
#define BIT(x) ((uint16_t)1 << (x))
/* CPU Module prototypes */
extern uint32_t cpu_cpsid(void);
extern void cpu_wfi(void);
/* Clock Signal Module constants */
#define CS_DCO_FREQUENCY_3 CS_CTL0_DCORSEL_1
#define CS_DCO_FREQUENCY_24 CS_CTL0_DCORSEL_4
/* Power Control Module constants */
#define PCM_KEY 0x695A0000
#define PCM_AM_LDO_VCORE0 0x00
#define PCM_AM_LDO_VCORE1 0x01
#define PCM_AM_DCDC_VCORE0 0x04
#define PCM_AM_DCDC_VCORE1 0x05
#define PCM_AM_LF_VCORE0 0x08
#define PCM_AM_LF_VCORE1 0x09
#define PCM_LPM0_LDO_VCORE0 0x10
#define PCM_LPM0_LDO_VCORE1 0x11
#define PCM_LPM0_DCDC_VCORE0 0x14
#define PCM_LPM0_DCDC_VCORE1 0x15
#define PCM_LPM0_LF_VCORE0 0x18
#define PCM_LPM0_LF_VCORE1 0x19
#define PCM_LPM3 0x20
#define PCM_LPM4 0x21
#define PCM_LPM35_VCORE0 0xC0
#define PCM_LPM45 0xA0
#define PCM_VCORE0 0x00
#define PCM_VCORE1 0x01
#define PCM_VCORELPM3 0x02
#define PCM_LDO_MODE 0x00
#define PCM_DCDC_MODE 0x01
#define PCM_LF_MODE 0x02
/* Power Control Module prototypes */
extern bool pcm_set_core_voltage_level(uint_fast8_t voltage_level);
extern uint8_t pcm_get_core_voltage_level(void);
extern bool pcm_set_power_mode(uint_fast8_t power_mode);
extern uint8_t pcm_get_power_mode(void);
extern bool pcm_set_power_state(uint_fast8_t power_state);
extern uint8_t pcm_get_power_state(void);
extern bool pcm_shutdown_device(uint32_t shutdown_mode);
extern bool pcm_goto_lpm0(void);
extern bool pcm_goto_lpm3(void);
extern bool pcm_goto_lpm4(void);
/* ROM API Function Pointers */
#define ROM_API_TABLE ((unsigned long *)0x02000800)
#define ROM_FLASH_CTL_TABLE ((unsigned long *)(ROM_API_TABLE[7]))
#define ROM_PCM_TABLE ((unsigned long *)(ROM_API_TABLE[13]))
#define ROM_WDT_TABLE ((unsigned long *)(ROM_API_TABLE[25]))
#define ROM_SYS_CTL_A_TABLE ((unsigned long *)(ROM_API_TABLE[26]))
#define ROM_FLASH_CTL_A_TABLE ((unsigned long *)(ROM_API_TABLE[27]))
#if defined(__MSP432P401X__)
#define ROM_FLASH_CTL_UNPROTECT_SECTOR \
((bool (*)(uint_fast8_t memory_space, \
uint32_t sector_mask))ROM_FLASH_CTL_TABLE[4])
#endif
#if defined(__MSP432P401X__)
#define ROM_FLASH_CTL_PROTECT_SECTOR \
((bool (*)(uint_fast8_t memory_space, \
uint32_t sector_mask))ROM_FLASH_CTL_TABLE[5])
#endif
#if defined(__MSP432P401X__)
#define ROM_FLASH_CTL_PERFORM_MASS_ERASE \
((bool (*)(void))ROM_FLASH_CTL_TABLE[8])
#endif
#if defined(__MSP432P401X__)
#define ROM_FLASH_CTL_ERASE_SECTOR \
((bool (*)(uint32_t addr))ROM_FLASH_CTL_TABLE[9])
#endif
#if defined(__MSP432P401X__)
#define ROM_FLASH_CTL_PROGRAM_MEMORY \
((bool (*)(void *src, void *dest, uint32_t length))ROM_FLASH_CTL_TABLE[10])
#endif
#if defined(__MSP432P401X__)
#define ROM_FLASH_CTL_SET_WAIT_STATE \
((void (*)(uint32_t bank, uint32_t wait_state))ROM_FLASH_CTL_TABLE[21])
#endif
#if defined(__MSP432P401X__)
#define ROM_FLASH_CTL_GET_WAIT_STATE \
((uint32_t (*)(uint32_t bank))ROM_FLASH_CTL_TABLE[22])
#endif
#if defined(__MSP432P401X__)
#define ROM_PCM_SET_CORE_VOLTAGE_LEVEL \
((bool (*)(uint_fast8_t voltage_level))ROM_PCM_TABLE[0])
#endif
#if defined(__MSP432P401X__)
#define ROM_PCM_GET_CORE_VOLTAGE_LEVEL \
((uint8_t (*)(void))ROM_PCM_TABLE[1])
#endif
#if defined(__MSP432P401X__)
#define ROM_PCM_SET_POWER_STATE \
((bool (*)(uint_fast8_t power_state))ROM_PCM_TABLE[6])
#endif
#if defined(__MSP432P401X__)
#define ROM_PCM_GET_POWER_STATE \
((uint8_t (*)(void))ROM_PCM_TABLE[8])
#endif
#if defined(__MSP432P401X__) || defined(__MSP432P411X__)
#define ROM_WDT_A_HOLD_TIMER \
((void (*)(void))ROM_WDT_TABLE[0])
#endif
#if defined(__MSP432P411X__)
#define ROM_SYS_CTL_A_GET_FLASH_SIZE \
((uint_least32_t (*)(void))ROM_SYS_CTL_A_TABLE[1])
#endif
#if defined(__MSP432P411X__)
#define ROM_SYS_CTL_A_GET_INFO_FLASH_SIZE \
((uint_least32_t (*)(void))ROM_SYS_CTL_A_TABLE[18])
#endif
#if defined(__MSP432P411X__)
#define ROM_FLASH_CTL_A_UNPROTECT_MEMORY \
((bool (*)(uint32_t start_addr, uint32_t end_addr))ROM_FLASH_CTL_A_TABLE[4])
#endif
#if defined(__MSP432P411X__)
#define ROM_FLASH_CTL_A_PROTECT_MEMORY \
((bool (*)(uint32_t start_addr, uint32_t end_addr))ROM_FLASH_CTL_A_TABLE[5])
#endif
#if defined(__MSP432P411X__)
#define ROM_FLASH_CTL_A_PERFORM_MASS_ERASE \
((bool (*)(void))ROM_FLASH_CTL_A_TABLE[8])
#endif
#if defined(__MSP432P411X__)
#define ROM_FLASH_CTL_A_ERASE_SECTOR \
((bool (*)(uint32_t addr))ROM_FLASH_CTL_A_TABLE[9])
#endif
#if defined(__MSP432P411X__)
#define ROM_FLASH_CTL_A_PROGRAM_MEMORY \
((bool (*)(void *src, void *dest, uint32_t length)) \
ROM_FLASH_CTL_A_TABLE[10])
#endif
#if defined(__MSP432P411X__)
#define ROM_FLASH_CTL_A_SET_WAIT_STATE \
((void (*)(uint32_t bank, uint32_t wait_state))ROM_FLASH_CTL_A_TABLE[21])
#endif
#if defined(__MSP432P411X__)
#define ROM_FLASH_CTL_A_GET_WAIT_STATE \
((uint32_t (*)(uint32_t bank))ROM_FLASH_CTL_A_TABLE[22])
#endif
/* Map API functions to ROM or locally built functions */
#ifdef ROM_FLASH_CTL_UNPROTECT_SECTOR
#define MAP_FLASH_CTL_UNPROTECT_SECTOR ROM_FLASH_CTL_UNPROTECT_SECTOR
#else
#define MAP_FLASH_CTL_UNPROTECT_SECTOR flash_ctl_unprotect_sector
#endif
#ifdef ROM_FLASH_CTL_PROTECT_SECTOR
#define MAP_FLASH_CTL_PROTECT_SECTOR ROM_FLASH_CTL_PROTECT_SECTOR
#else
#define MAP_FLASH_CTL_PROTECT_SECTOR flash_ctl_protect_sector
#endif
#ifdef ROM_FLASH_CTL_PERFORM_MASS_ERASE
#define MAP_FLASH_CTL_PERFORM_MASS_ERASE ROM_FLASH_CTL_PERFORM_MASS_ERASE
#else
#define MAP_FLASH_CTL_PERFORM_MASS_ERASE flash_ctl_perform_mass_erase
#endif
#ifdef ROM_FLASH_CTL_ERASE_SECTOR
#define MAP_FLASH_CTL_ERASE_SECTOR ROM_FLASH_CTL_ERASE_SECTOR
#else
#define MAP_FLASH_CTL_ERASE_SECTOR flash_ctl_erase_sector
#endif
#ifdef ROM_FLASH_CTL_PROGRAM_MEMORY
#define MAP_FLASH_CTL_PROGRAM_MEMORY ROM_FLASH_CTL_PROGRAM_MEMORY
#else
#define MAP_FLASH_CTL_PROGRAM_MEMORY flash_ctl_program_memory
#endif
#ifdef ROM_FLASH_CTL_SET_WAIT_STATE
#define MAP_FLASH_CTL_SET_WAIT_STATE ROM_FLASH_CTL_SET_WAIT_STATE
#else
#define MAP_FLASH_CTL_SET_WAIT_STATE flash_ctl_set_wait_state
#endif
#ifdef ROM_FLASH_CTL_GET_WAIT_STATE
#define MAP_FLASH_CTL_GET_WAIT_STATE ROM_FLASH_CTL_GET_WAIT_STATE
#else
#define MAP_FLASH_CTL_GET_WAIT_STATE flash_ctl_get_wait_state
#endif
#ifdef ROM_PCM_SET_CORE_VOLTAGE_LEVEL
#define MAP_PCM_SET_CORE_VOLTAGE_LEVEL ROM_PCM_SET_CORE_VOLTAGE_LEVEL
#else
#define MAP_PCM_SET_CORE_VOLTAGE_LEVEL pcm_set_core_voltage_level
#endif
#ifdef ROM_PCM_GET_CORE_VOLTAGE_LEVEL
#define MAP_PCM_GET_CORE_VOLTAGE_LEVEL ROM_PCM_GET_CORE_VOLTAGE_LEVEL
#else
#define MAP_PCM_GET_CORE_VOLTAGE_LEVEL pcm_get_core_voltage_level
#endif
#ifdef ROM_PCM_SET_POWER_STATE
#define MAP_PCM_SET_POWER_STATE ROM_PCM_SET_POWER_STATE
#else
#define MAP_PCM_SET_POWER_STATE pcm_set_power_state
#endif
#ifdef ROM_PCM_GET_POWER_STATE
#define MAP_PCM_GET_POWER_STATE ROM_PCM_GET_POWER_STATE
#else
#define MAP_PCM_GET_POWER_STATE pcm_get_power_state
#endif
#ifdef ROM_WDT_A_HOLD_TIMER
#define MAP_WDT_A_HOLD_TIMER ROM_WDT_A_HOLD_TIMER
#else
#define MAP_WDT_A_HOLD_TIMER wdt_a_hold_timer
#endif
#ifdef ROM_SYS_CTL_A_GET_FLASH_SIZE
#define MAP_SYS_CTL_A_GET_FLASH_SIZE ROM_SYS_CTL_A_GET_FLASH_SIZE
#else
#define MAP_SYS_CTL_A_GET_FLASH_SIZE sys_ctl_a_get_flash_size
#endif
#ifdef ROM_SYS_CTL_A_GET_INFO_FLASH_SIZE
#define MAP_SYS_CTL_A_GET_INFO_FLASH_SIZE ROM_SYS_CTL_A_GET_INFO_FLASH_SIZE
#else
#define MAP_SYS_CTL_A_GET_INFO_FLASH_SIZE sys_ctl_a_get_info_flash_size
#endif
#ifdef ROM_FLASH_CTL_A_UNPROTECT_MEMORY
#define MAP_FLASH_CTL_A_UNPROTECT_MEMORY ROM_FLASH_CTL_A_UNPROTECT_MEMORY
#else
#define MAP_FLASH_CTL_A_UNPROTECT_MEMORY flash_ctl_a_unprotect_memory
#endif
#ifdef ROM_FLASH_CTL_A_PROTECT_MEMORY
#define MAP_FLASH_CTL_A_PROTECT_MEMORY ROM_FLASH_CTL_A_PROTECT_MEMORY
#else
#define MAP_FLASH_CTL_A_PROTECT_MEMORY flash_ctl_a_protect_memory
#endif
#ifdef ROM_FLASH_CTL_A_PERFORM_MASS_ERASE
#define MAP_FLASH_CTL_A_PERFORM_MASS_ERASE ROM_FLASH_CTL_A_PERFORM_MASS_ERASE
#else
#define MAP_FLASH_CTL_A_PERFORM_MASS_ERASE flash_ctl_a_perform_mass_erase
#endif
#ifdef ROM_FLASH_CTL_A_ERASE_SECTOR
#define MAP_FLASH_CTL_A_ERASE_SECTOR ROM_FLASH_CTL_A_ERASE_SECTOR
#else
#define MAP_FLASH_CTL_A_ERASE_SECTOR flash_ctl_a_erase_sector
#endif
#ifdef ROM_FLASH_CTL_A_PROGRAM_MEMORY
#define MAP_FLASH_CTL_A_PROGRAM_MEMORY ROM_FLASH_CTL_A_PROGRAM_MEMORY
#else
#define MAP_FLASH_CTL_A_PROGRAM_MEMORY flash_ctl_a_program_memory
#endif
#ifdef ROM_FLASH_CTL_A_SET_WAIT_STATE
#define MAP_FLASH_CTL_A_SET_WAIT_STATE ROM_FLASH_CTL_A_SET_WAIT_STATE
#else
#define MAP_FLASH_CTL_A_SET_WAIT_STATE flash_ctl_a_set_wait_state
#endif
#ifdef ROM_FLASH_CTL_A_GET_WAIT_STATE
#define MAP_FLASH_CTL_A_GET_WAIT_STATE ROM_FLASH_CTL_A_GET_WAIT_STATE
#else
#define MAP_FLASH_CTL_A_GET_WAIT_STATE flash_ctl_a_get_wait_state
#endif
/* Real Time Clock Module prototypes */
extern void rtc_c_hold_clock(void);
/* Watchdog Timer Module prototypes */
extern void wdt_a_hold_timer(void);
#if defined(__MCU_HAS_FLCTL_A__)
#define FLASH_A_BANK0 0x00
#define FLASH_A_BANK1 0x01
#define __INFO_FLASH_A_TECH_START__ 0x00200000
#define __INFO_FLASH_A_TECH_MIDDLE__ 0x00204000
#endif
#if defined(__MCU_HAS_FLCTL__)
#define FLASH_BANK0 0x00
#define FLASH_BANK1 0x01
#define FLASH_MAIN_MEMORY_SPACE_BANK0 0x01
#define FLASH_MAIN_MEMORY_SPACE_BANK1 0x02
#define FLASH_INFO_MEMORY_SPACE_BANK0 0x03
#define FLASH_INFO_MEMORY_SPACE_BANK1 0x04
#define FLASH_SECTOR0 FLCTL_BANK0_MAIN_WEPROT_PROT0
#define FLASH_SECTOR1 FLCTL_BANK0_MAIN_WEPROT_PROT1
#endif
#ifdef __cplusplus
}
#endif
#endif /* OPENOCD_LOADERS_FLASH_MSP432_DRIVERLIB_H */

View File

@ -0,0 +1,351 @@
/******************************************************************************
*
* Copyright (C) 2017-2018 Texas Instruments Incorporated - http://www.ti.com/
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* distribution.
*
* Neither the name of Texas Instruments Incorporated nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************/
#include <stdint.h>
#include <stdbool.h>
#include "driverlib.h"
#include "MSP432E4_FlashLibIf.h"
/* Local prototypes */
void msp432_flash_init(void);
void msp432_flash_mass_erase(void);
void msp432_flash_sector_erase(void);
void msp432_flash_write(void);
void msp432_flash_continous_write(void);
void msp432_flash_exit(void);
int main(void)
{
/* Disable interrupts */
__asm(" cpsid i");
/* Halt watchdog */
SYSCTL->RCGCWD &= ~(SYSCTL_RCGCWD_R1 + SYSCTL_RCGCWD_R0);
while (1) {
switch (FLASH_LOADER->FLASH_FUNCTION) {
case FLASH_INIT:
FLASH_LOADER->RETURN_CODE = FLASH_BUSY;
msp432_flash_init();
FLASH_LOADER->FLASH_FUNCTION = 0;
break;
case FLASH_MASS_ERASE:
FLASH_LOADER->RETURN_CODE = FLASH_BUSY;
msp432_flash_mass_erase();
FLASH_LOADER->FLASH_FUNCTION = 0;
break;
case FLASH_SECTOR_ERASE:
FLASH_LOADER->RETURN_CODE = FLASH_BUSY;
msp432_flash_sector_erase();
FLASH_LOADER->FLASH_FUNCTION = 0;
break;
case FLASH_PROGRAM:
case FLASH_CONTINUOUS_PROGRAM:
FLASH_LOADER->RETURN_CODE = FLASH_BUSY;
msp432_flash_continous_write();
FLASH_LOADER->FLASH_FUNCTION = 0;
break;
case FLASH_EXIT:
FLASH_LOADER->RETURN_CODE = FLASH_BUSY;
msp432_flash_exit();
FLASH_LOADER->FLASH_FUNCTION = 0;
break;
case FLASH_NO_COMMAND:
break;
default:
FLASH_LOADER->RETURN_CODE = FLASH_WRONG_COMMAND;
break;
}
}
}
/* Initialize flash */
void msp432_flash_init(void)
{
SCB->VTOR = 0x20000000;
FLASH_LOADER->RETURN_CODE = FLASH_SUCCESS;
}
/* Erase entire flash */
void msp432_flash_mass_erase(void)
{
bool success = false;
/* Clear the flash access and error interrupts. */
FLASH_CTRL->FCMISC = (FLASH_FCMISC_AMISC | FLASH_FCMISC_VOLTMISC |
FLASH_FCMISC_ERMISC | FLASH_FCMISC_PMISC);
/* Trigger mass erase */
FLASH_CTRL->FMC = FLASH_FMC_WRKEY | FLASH_FMC_MERASE;
while (FLASH_CTRL->FMC & FLASH_FMC_MERASE)
;
/* Return an error if an access violation occurred. */
success = !(FLASH_CTRL->FCRIS & (FLASH_FCRIS_ARIS | FLASH_FCRIS_VOLTRIS |
FLASH_FCRIS_ERRIS));
if (!success)
FLASH_LOADER->RETURN_CODE = FLASH_VERIFY_ERROR;
else
FLASH_LOADER->RETURN_CODE = FLASH_SUCCESS;
}
/* Erase one flash sector */
void msp432_flash_sector_erase(void)
{
bool success = false;
/* Clear the flash access and error interrupts. */
FLASH_CTRL->FCMISC = (FLASH_FCMISC_AMISC | FLASH_FCMISC_VOLTMISC |
FLASH_FCMISC_ERMISC | FLASH_FCMISC_PMISC);
/* Set 16kB aligned flash page address to be erased (16kB block) */
FLASH_CTRL->FMA = FLASH_LOADER->DST_ADDRESS;
/* Trigger sector erase (erase flash page) */
FLASH_CTRL->FMC = FLASH_FMC_WRKEY | FLASH_FMC_ERASE;
while (FLASH_CTRL->FMC & FLASH_FMC_ERASE)
;
/* Return an error if an access violation occurred. */
success = !(FLASH_CTRL->FCRIS & (FLASH_FCRIS_ARIS | FLASH_FCRIS_VOLTRIS |
FLASH_FCRIS_ERRIS));
if (!success)
FLASH_LOADER->RETURN_CODE = FLASH_ERROR;
else
FLASH_LOADER->RETURN_CODE = FLASH_SUCCESS;
}
/* Write data to flash */
void msp432_flash_continous_write(void)
{
bool buffer1_in_use = false;
bool buffer2_in_use = false;
uint32_t *src_address = NULL;
bool success = true;
uint32_t i = 0;
uint32_t address = FLASH_LOADER->DST_ADDRESS;
uint32_t data_to_write = FLASH_LOADER->SRC_LENGTH;
int32_t write_package = 0;
/* Clear the flash access and error interrupts. */
FLASH_CTRL->FCMISC = (FLASH_FCMISC_AMISC | FLASH_FCMISC_VOLTMISC |
FLASH_FCMISC_INVDMISC | FLASH_FCMISC_PROGMISC | FLASH_FCMISC_PMISC);
do {
if (data_to_write > SRC_LENGTH_MAX) {
write_package = SRC_LENGTH_MAX;
data_to_write -= write_package;
} else {
write_package = data_to_write;
data_to_write -= write_package;
}
while (!(FLASH_LOADER->BUFFER1_STATUS_REGISTER & BUFFER_DATA_READY) &&
!(FLASH_LOADER->BUFFER2_STATUS_REGISTER & BUFFER_DATA_READY))
;
if (FLASH_LOADER->BUFFER1_STATUS_REGISTER & BUFFER_DATA_READY) {
FLASH_LOADER->BUFFER1_STATUS_REGISTER |= BUFFER_ACTIVE;
src_address = (uint32_t *) RAM_LOADER_BUFFER1;
buffer1_in_use = true;
} else if (FLASH_LOADER->BUFFER2_STATUS_REGISTER & BUFFER_DATA_READY) {
FLASH_LOADER->BUFFER2_STATUS_REGISTER |= BUFFER_ACTIVE;
src_address = (uint32_t *) RAM_LOADER_BUFFER2;
buffer2_in_use = true;
}
/*
* The flash hardware can only write complete words to flash. If
* an unaligned address is passed in, we must do a read-modify-write
* on a word with enough bytes to align the rest of the buffer. And
* if less than a whole word remains at the end, we must also do a
* read-modify-write on a final word to finish up.
*/
if (0 != (address & 0x3)) {
uint32_t head;
uint8_t *ui8head = (uint8_t *)&head;
uint8_t *buffer = (uint8_t *)src_address;
/* Get starting offset for data to write (will be 1 to 3) */
uint32_t head_offset = address & 0x03;
/* Get the aligned address to write this first word to */
uint32_t head_address = address & 0xfffffffc;
/* Retrieve what is already in flash at the head address */
head = *(uint32_t *)head_address;
/* Substitute in the new data to write */
while ((write_package > 0) && (head_offset < 4)) {
ui8head[head_offset] = *buffer;
head_offset++;
address++;
buffer++;
write_package--;
}
src_address = (uint32_t *)buffer;
FLASH_CTRL->FMD = head;
FLASH_CTRL->FMA = head_address;
FLASH_CTRL->FMC = FLASH_FMC_WRKEY | FLASH_FMC_WRITE;
/* Wait until the word has been programmed. */
while (FLASH_CTRL->FMC & FLASH_FMC_WRITE)
;
/* Return an error if an access violation occurred. */
success = !(FLASH_CTRL->FCRIS & (FLASH_FCRIS_ARIS |
FLASH_FCRIS_ERIS | FLASH_FCRIS_INVDRIS | FLASH_FCRIS_PROGRIS));
}
/* Program a word at a time until aligned on 32-word boundary */
while ((write_package >= 4) && ((address & 0x7f) != 0) && success) {
FLASH_CTRL->FMD = *src_address++;
FLASH_CTRL->FMA = address;
FLASH_CTRL->FMC = FLASH_FMC_WRKEY | FLASH_FMC_WRITE;
/* Wait until the word has been programmed. */
while (FLASH_CTRL->FMC & FLASH_FMC_WRITE)
;
/* Prepare for next word to write */
write_package -= 4;
address += 4;
/* Return an error if an access violation occurred. */
success = !(FLASH_CTRL->FCRIS & (FLASH_FCRIS_ARIS |
FLASH_FCRIS_ERIS | FLASH_FCRIS_INVDRIS | FLASH_FCRIS_PROGRIS));
}
/* Program data in 32-word blocks */
while ((write_package >= 32) && success) {
/* Loop over the words in this 32-word block. */
i = 0;
do {
FLASH_CTRL->FWBN[i] = *src_address++;
write_package -= 4;
i++;
} while ((write_package > 0) && (i < 32));
FLASH_CTRL->FMA = address;
FLASH_CTRL->FMC2 = FLASH_FMC_WRKEY | FLASH_FMC2_WRBUF;
/* Wait until the write buffer has been programmed. */
while (FLASH_CTRL->FMC2 & FLASH_FMC2_WRBUF)
;
/* Increment destination address by words written */
address += 128;
/* Return an error if an access violation occurred. */
success = !(FLASH_CTRL->FCRIS & (FLASH_FCRIS_ARIS |
FLASH_FCRIS_ERIS | FLASH_FCRIS_INVDRIS | FLASH_FCRIS_PROGRIS));
}
/* Program a word at a time on left over data */
while ((write_package >= 4) && success) {
FLASH_CTRL->FMD = *src_address++;
FLASH_CTRL->FMA = address;
FLASH_CTRL->FMC = FLASH_FMC_WRKEY | FLASH_FMC_WRITE;
/* Wait until the word has been programmed. */
while (FLASH_CTRL->FMC & FLASH_FMC_WRITE)
;
/* Prepare for next word to write */
write_package -= 4;
address += 4;
/* Return an error if an access violation occurred. */
success = !(FLASH_CTRL->FCRIS & (FLASH_FCRIS_ARIS |
FLASH_FCRIS_ERIS | FLASH_FCRIS_INVDRIS | FLASH_FCRIS_PROGRIS));
}
if ((write_package > 0) && success) {
uint32_t tail;
uint8_t *ui8tail = (uint8_t *)&tail;
uint8_t *buffer = (uint8_t *)src_address;
/* Set starting offset for data to write */
uint32_t tail_offset = 0;
/* Get the address to write this last word to */
uint32_t tail_address = address;
/* Retrieve what is already in flash at the tail address */
tail = *(uint32_t *)address;
/* Substitute in the new data to write */
while (write_package > 0) {
ui8tail[tail_offset] = *buffer;
tail_offset++;
address++;
buffer++;
write_package--;
}
FLASH_CTRL->FMD = tail;
FLASH_CTRL->FMA = tail_address;
FLASH_CTRL->FMC = FLASH_FMC_WRKEY | FLASH_FMC_WRITE;
/* Wait until the word has been programmed. */
while (FLASH_CTRL->FMC & FLASH_FMC_WRITE)
;
/* Return an error if an access violation occurred. */
success = !(FLASH_CTRL->FCRIS & (FLASH_FCRIS_ARIS |
FLASH_FCRIS_ERIS | FLASH_FCRIS_INVDRIS | FLASH_FCRIS_PROGRIS));
}
if (buffer1_in_use) {
FLASH_LOADER->BUFFER1_STATUS_REGISTER &=
~(BUFFER_ACTIVE | BUFFER_DATA_READY);
buffer1_in_use = false;
} else if (buffer2_in_use) {
FLASH_LOADER->BUFFER2_STATUS_REGISTER &=
~(BUFFER_ACTIVE | BUFFER_DATA_READY);
buffer2_in_use = false;
}
} while (success && data_to_write);
if (!success)
FLASH_LOADER->RETURN_CODE = FLASH_ERROR;
else
FLASH_LOADER->RETURN_CODE = FLASH_SUCCESS;
}
/* Exit flash programming */
void msp432_flash_exit(void)
{
SCB->VTOR = 0x00000000;
FLASH_LOADER->RETURN_CODE = FLASH_SUCCESS;
}

View File

@ -0,0 +1,385 @@
/******************************************************************************
*
* Copyright (C) 2013-2018 Texas Instruments Incorporated - http://www.ti.com/
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* distribution.
*
* Neither the name of Texas Instruments Incorporated nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************/
#include <stdint.h>
#include <stdbool.h>
#include "driverlib.h"
#include "MSP432P4_FlashLibIf.h"
/* Number of erase repeats until timeout */
#define FLASH_MAX_REPEATS 5
/* Local prototypes */
void msp432_flash_init(void);
void msp432_flash_mass_erase(void);
void msp432_flash_sector_erase(void);
void msp432_flash_write(void);
void msp432_flash_continous_write(void);
void msp432_flash_exit(void);
void unlock_flash_sectors(void);
void unlock_all_flash_sectors(void);
void lock_all_flash_sectors(void);
void __cs_set_dco_frequency_range(uint32_t dco_freq);
static bool program_device(void *src, void *dest, uint32_t length);
struct backup_params {
uint32_t BANK0_WAIT_RESTORE;
uint32_t BANK1_WAIT_RESTORE;
uint32_t CS_DC0_FREQ_RESTORE;
uint8_t VCORE_LEVEL_RESTORE;
uint8_t PCM_VCORE_LEVEL_RESTORE;
};
#define BACKUP_PARAMS ((struct backup_params *) 0x20000180)
/* Main with trampoline */
int main(void)
{
/* Halt watchdog */
MAP_WDT_A_HOLD_TIMER();
/* Disable interrupts */
cpu_cpsid();
while (1) {
switch (FLASH_LOADER->FLASH_FUNCTION) {
case FLASH_INIT:
FLASH_LOADER->RETURN_CODE = FLASH_BUSY;
msp432_flash_init();
FLASH_LOADER->FLASH_FUNCTION = 0;
break;
case FLASH_MASS_ERASE:
FLASH_LOADER->RETURN_CODE = FLASH_BUSY;
msp432_flash_mass_erase();
FLASH_LOADER->FLASH_FUNCTION = 0;
break;
case FLASH_SECTOR_ERASE:
FLASH_LOADER->RETURN_CODE = FLASH_BUSY;
msp432_flash_sector_erase();
FLASH_LOADER->FLASH_FUNCTION = 0;
break;
case FLASH_PROGRAM:
FLASH_LOADER->RETURN_CODE = FLASH_BUSY;
msp432_flash_write();
FLASH_LOADER->FLASH_FUNCTION = 0;
break;
case FLASH_CONTINUOUS_PROGRAM:
FLASH_LOADER->RETURN_CODE = FLASH_BUSY;
msp432_flash_continous_write();
FLASH_LOADER->FLASH_FUNCTION = 0;
break;
case FLASH_EXIT:
FLASH_LOADER->RETURN_CODE = FLASH_BUSY;
msp432_flash_exit();
FLASH_LOADER->FLASH_FUNCTION = 0;
break;
case FLASH_NO_COMMAND:
break;
default:
FLASH_LOADER->RETURN_CODE = FLASH_WRONG_COMMAND;
break;
}
}
}
/* Initialize flash */
void msp432_flash_init(void)
{
bool success = false;
/* Point to vector table in RAM */
SCB->VTOR = (uint32_t)0x01000000;
/* backup system parameters */
BACKUP_PARAMS->BANK0_WAIT_RESTORE =
MAP_FLASH_CTL_GET_WAIT_STATE(FLASH_BANK0);
BACKUP_PARAMS->BANK1_WAIT_RESTORE =
MAP_FLASH_CTL_GET_WAIT_STATE(FLASH_BANK1);
BACKUP_PARAMS->VCORE_LEVEL_RESTORE = MAP_PCM_GET_CORE_VOLTAGE_LEVEL();
BACKUP_PARAMS->PCM_VCORE_LEVEL_RESTORE = MAP_PCM_GET_POWER_STATE();
BACKUP_PARAMS->CS_DC0_FREQ_RESTORE = CS->CTL0 & CS_CTL0_DCORSEL_MASK;
/* set parameters for flashing */
success = MAP_PCM_SET_POWER_STATE(PCM_AM_LDO_VCORE0);
/* Set Flash wait states to 2 */
MAP_FLASH_CTL_SET_WAIT_STATE(FLASH_BANK0, 2);
MAP_FLASH_CTL_SET_WAIT_STATE(FLASH_BANK1, 2);
/* Set CPU speed to 24MHz */
__cs_set_dco_frequency_range(CS_DCO_FREQUENCY_24);
if (!success) {
/* Indicate failed power switch */
FLASH_LOADER->RETURN_CODE = FLASH_POWER_ERROR;
} else
FLASH_LOADER->RETURN_CODE = FLASH_SUCCESS;
}
/* Erase entire flash */
void msp432_flash_mass_erase(void)
{
bool success = false;
/* Allow flash writes */
unlock_flash_sectors();
/* Allow some mass erase repeats before timeout with error */
int erase_repeats = FLASH_MAX_REPEATS;
while (!success && (erase_repeats > 0)) {
/* Mass erase with post-verify */
success = MAP_FLASH_CTL_PERFORM_MASS_ERASE();
erase_repeats--;
}
if (erase_repeats == 0)
FLASH_LOADER->RETURN_CODE = FLASH_VERIFY_ERROR;
else
FLASH_LOADER->RETURN_CODE = FLASH_SUCCESS;
/* Block flash writes */
lock_all_flash_sectors();
}
/* Erase one flash sector */
void msp432_flash_sector_erase(void)
{
bool success = false;
/* Allow flash writes */
unlock_all_flash_sectors();
/* Allow some sector erase repeats before timeout with error */
int erase_repeats = FLASH_MAX_REPEATS;
while (!success && (erase_repeats > 0)) {
/* Sector erase with post-verify */
success = MAP_FLASH_CTL_ERASE_SECTOR(FLASH_LOADER->DST_ADDRESS);
erase_repeats--;
}
if (erase_repeats == 0)
FLASH_LOADER->RETURN_CODE = FLASH_ERROR;
else
FLASH_LOADER->RETURN_CODE = FLASH_SUCCESS;
/* Block flash writes */
lock_all_flash_sectors();
}
/* Write data to flash with the help of DriverLib */
void msp432_flash_write(void)
{
bool success = false;
/* Allow flash writes */
unlock_all_flash_sectors();
while (!(FLASH_LOADER->BUFFER1_STATUS_REGISTER & BUFFER_DATA_READY))
;
FLASH_LOADER->BUFFER1_STATUS_REGISTER |= BUFFER_ACTIVE;
/* Program memory */
success = program_device((uint32_t *)RAM_LOADER_BUFFER1,
(void *)FLASH_LOADER->DST_ADDRESS, FLASH_LOADER->SRC_LENGTH);
FLASH_LOADER->BUFFER1_STATUS_REGISTER &=
~(BUFFER_ACTIVE | BUFFER_DATA_READY);
/* Block flash writes */
lock_all_flash_sectors();
if (!success)
FLASH_LOADER->RETURN_CODE = FLASH_ERROR;
else
FLASH_LOADER->RETURN_CODE = FLASH_SUCCESS;
}
/* Write data to flash with the help of DriverLib with auto-increment */
void msp432_flash_continous_write(void)
{
bool buffer1_in_use = false;
bool buffer2_in_use = false;
uint32_t *src_address = NULL;
bool success = false;
uint32_t bytes_to_write = FLASH_LOADER->SRC_LENGTH;
uint32_t write_package = 0;
uint32_t start_addr = FLASH_LOADER->DST_ADDRESS;
while (bytes_to_write > 0) {
if (bytes_to_write > SRC_LENGTH_MAX) {
write_package = SRC_LENGTH_MAX;
bytes_to_write -= write_package;
} else {
write_package = bytes_to_write;
bytes_to_write -= write_package;
}
unlock_all_flash_sectors();
while (!(FLASH_LOADER->BUFFER1_STATUS_REGISTER & BUFFER_DATA_READY) &&
!(FLASH_LOADER->BUFFER2_STATUS_REGISTER & BUFFER_DATA_READY))
;
if (FLASH_LOADER->BUFFER1_STATUS_REGISTER & BUFFER_DATA_READY) {
FLASH_LOADER->BUFFER1_STATUS_REGISTER |= BUFFER_ACTIVE;
src_address = (uint32_t *)RAM_LOADER_BUFFER1;
buffer1_in_use = true;
} else if (FLASH_LOADER->BUFFER2_STATUS_REGISTER & BUFFER_DATA_READY) {
FLASH_LOADER->BUFFER2_STATUS_REGISTER |= BUFFER_ACTIVE;
src_address = (uint32_t *)RAM_LOADER_BUFFER2;
buffer2_in_use = true;
}
if (buffer1_in_use || buffer2_in_use) {
success = program_device(src_address,
(void *)start_addr, write_package);
if (buffer1_in_use)
P6->OUT &= ~BIT4; /* Program from B1 */
else if (buffer2_in_use)
P3->OUT &= ~BIT6; /* Program from B1 */
start_addr += write_package;
}
if (buffer1_in_use) {
FLASH_LOADER->BUFFER1_STATUS_REGISTER &=
~(BUFFER_ACTIVE | BUFFER_DATA_READY);
buffer1_in_use = false;
} else if (buffer2_in_use) {
FLASH_LOADER->BUFFER2_STATUS_REGISTER &=
~(BUFFER_ACTIVE | BUFFER_DATA_READY);
buffer2_in_use = false;
}
/* Block flash writes */
lock_all_flash_sectors();
if (!success) {
FLASH_LOADER->RETURN_CODE = FLASH_ERROR;
break;
}
}
if (success)
FLASH_LOADER->RETURN_CODE = FLASH_SUCCESS;
}
/* Unlock Main/Info Flash sectors */
void unlock_flash_sectors(void)
{
if (FLASH_LOADER->ERASE_PARAM & ERASE_MAIN) {
MAP_FLASH_CTL_UNPROTECT_SECTOR(FLASH_MAIN_MEMORY_SPACE_BANK0,
0xFFFFFFFF);
MAP_FLASH_CTL_UNPROTECT_SECTOR(FLASH_MAIN_MEMORY_SPACE_BANK1,
0xFFFFFFFF);
}
if (FLASH_LOADER->ERASE_PARAM & ERASE_INFO) {
MAP_FLASH_CTL_UNPROTECT_SECTOR(FLASH_INFO_MEMORY_SPACE_BANK0,
FLASH_SECTOR0 | FLASH_SECTOR1);
if (FLASH_LOADER->UNLOCK_BSL == UNLOCK_BSL_KEY)
MAP_FLASH_CTL_UNPROTECT_SECTOR(FLASH_INFO_MEMORY_SPACE_BANK1,
FLASH_SECTOR0 | FLASH_SECTOR1);
}
}
/* Unlock All Flash sectors */
void unlock_all_flash_sectors(void)
{
MAP_FLASH_CTL_UNPROTECT_SECTOR(FLASH_MAIN_MEMORY_SPACE_BANK0, 0xFFFFFFFF);
MAP_FLASH_CTL_UNPROTECT_SECTOR(FLASH_MAIN_MEMORY_SPACE_BANK1, 0xFFFFFFFF);
MAP_FLASH_CTL_UNPROTECT_SECTOR(FLASH_INFO_MEMORY_SPACE_BANK0,
FLASH_SECTOR0 | FLASH_SECTOR1);
if (FLASH_LOADER->UNLOCK_BSL == UNLOCK_BSL_KEY)
MAP_FLASH_CTL_UNPROTECT_SECTOR(FLASH_INFO_MEMORY_SPACE_BANK1,
FLASH_SECTOR0 | FLASH_SECTOR1);
}
/* Lock all Flash sectors */
void lock_all_flash_sectors(void)
{
MAP_FLASH_CTL_PROTECT_SECTOR(FLASH_MAIN_MEMORY_SPACE_BANK0, 0xFFFFFFFF);
MAP_FLASH_CTL_PROTECT_SECTOR(FLASH_MAIN_MEMORY_SPACE_BANK1, 0xFFFFFFFF);
MAP_FLASH_CTL_PROTECT_SECTOR(FLASH_INFO_MEMORY_SPACE_BANK0,
FLASH_SECTOR0 | FLASH_SECTOR1);
MAP_FLASH_CTL_PROTECT_SECTOR(FLASH_INFO_MEMORY_SPACE_BANK1,
FLASH_SECTOR0 | FLASH_SECTOR1);
}
/* Force DCO frequency range */
void __cs_set_dco_frequency_range(uint32_t dco_freq)
{
/* Unlocking the CS Module */
CS->KEY = CS_KEY_VAL;
/* Resetting Tuning Parameters and Setting the frequency */
CS->CTL0 = (CS->CTL0 & ~CS_CTL0_DCORSEL_MASK) | dco_freq;
/* Locking the CS Module */
CS->KEY = 0;
}
/* Exit flash programming */
void msp432_flash_exit(void)
{
bool success = false;
/* Restore modified registers, in reverse order */
__cs_set_dco_frequency_range(CS_DCO_FREQUENCY_3);
MAP_FLASH_CTL_SET_WAIT_STATE(FLASH_BANK0,
BACKUP_PARAMS->BANK0_WAIT_RESTORE);
MAP_FLASH_CTL_SET_WAIT_STATE(FLASH_BANK1,
BACKUP_PARAMS->BANK1_WAIT_RESTORE);
success = MAP_PCM_SET_POWER_STATE(BACKUP_PARAMS->PCM_VCORE_LEVEL_RESTORE);
success &= MAP_PCM_SET_CORE_VOLTAGE_LEVEL(
BACKUP_PARAMS->VCORE_LEVEL_RESTORE);
__cs_set_dco_frequency_range(BACKUP_PARAMS->CS_DC0_FREQ_RESTORE);
/* Point to vector table in Flash */
SCB->VTOR = (uint32_t)0x00000000;
if (!success)
FLASH_LOADER->RETURN_CODE = FLASH_ERROR;
else
FLASH_LOADER->RETURN_CODE = FLASH_SUCCESS;
}
static bool program_device(void *src, void *dest, uint32_t length)
{
return MAP_FLASH_CTL_PROGRAM_MEMORY(src, dest, length);
}

View File

@ -0,0 +1,391 @@
/******************************************************************************
*
* Copyright (C) 2013-2018 Texas Instruments Incorporated - http://www.ti.com/
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* distribution.
*
* Neither the name of Texas Instruments Incorporated nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************/
#include <stdint.h>
#include <stdbool.h>
#include "driverlib.h"
#include "MSP432P4_FlashLibIf.h"
/* Number of erase repeats until timeout */
#define FLASH_MAX_REPEATS 5
/* Local prototypes */
void msp432_flash_init(void);
void msp432_flash_mass_erase(void);
void msp432_flash_sector_erase(void);
void msp432_flash_write(void);
void msp432_flash_continous_write(void);
void msp432_flash_exit(void);
void unlock_flash_sectors(void);
void unlock_all_flash_sectors(void);
void lock_all_flash_sectors(void);
void __cs_set_dco_frequency_range(uint32_t dco_freq);
static bool program_device(void *src, void *dest, uint32_t length);
struct backup_params {
uint32_t BANK0_WAIT_RESTORE;
uint32_t BANK1_WAIT_RESTORE;
uint32_t CS_DC0_FREQ_RESTORE;
uint8_t VCORE_LEVEL_RESTORE;
uint8_t PCM_VCORE_LEVEL_RESTORE;
};
#define BACKUP_PARAMS ((struct backup_params *) 0x20000180)
#define INFO_FLASH_START __INFO_FLASH_A_TECH_START__
#define INFO_FLASH_MIDDLE __INFO_FLASH_A_TECH_MIDDLE__
#define BSL_FLASH_START BSL_API_TABLE_ADDR
/* Main with trampoline */
int main(void)
{
/* Halt watchdog */
MAP_WDT_A_HOLD_TIMER();
/* Disable interrupts */
cpu_cpsid();
while (1) {
switch (FLASH_LOADER->FLASH_FUNCTION) {
case FLASH_INIT:
FLASH_LOADER->RETURN_CODE = FLASH_BUSY;
msp432_flash_init();
FLASH_LOADER->FLASH_FUNCTION = 0;
break;
case FLASH_MASS_ERASE:
FLASH_LOADER->RETURN_CODE = FLASH_BUSY;
msp432_flash_mass_erase();
FLASH_LOADER->FLASH_FUNCTION = 0;
break;
case FLASH_SECTOR_ERASE:
FLASH_LOADER->RETURN_CODE = FLASH_BUSY;
msp432_flash_sector_erase();
FLASH_LOADER->FLASH_FUNCTION = 0;
break;
case FLASH_PROGRAM:
FLASH_LOADER->RETURN_CODE = FLASH_BUSY;
msp432_flash_write();
FLASH_LOADER->FLASH_FUNCTION = 0;
break;
case FLASH_CONTINUOUS_PROGRAM:
FLASH_LOADER->RETURN_CODE = FLASH_BUSY;
msp432_flash_continous_write();
FLASH_LOADER->FLASH_FUNCTION = 0;
break;
case FLASH_EXIT:
FLASH_LOADER->RETURN_CODE = FLASH_BUSY;
msp432_flash_exit();
FLASH_LOADER->FLASH_FUNCTION = 0;
break;
case FLASH_NO_COMMAND:
break;
default:
FLASH_LOADER->RETURN_CODE = FLASH_WRONG_COMMAND;
break;
}
}
}
/* Initialize flash */
void msp432_flash_init(void)
{
bool success = false;
/* Point to vector table in RAM */
SCB->VTOR = (uint32_t)0x01000000;
/* backup system parameters */
BACKUP_PARAMS->BANK0_WAIT_RESTORE =
MAP_FLASH_CTL_A_GET_WAIT_STATE(FLASH_A_BANK0);
BACKUP_PARAMS->BANK1_WAIT_RESTORE =
MAP_FLASH_CTL_A_GET_WAIT_STATE(FLASH_A_BANK1);
BACKUP_PARAMS->VCORE_LEVEL_RESTORE = MAP_PCM_GET_CORE_VOLTAGE_LEVEL();
BACKUP_PARAMS->PCM_VCORE_LEVEL_RESTORE = MAP_PCM_GET_POWER_STATE();
BACKUP_PARAMS->CS_DC0_FREQ_RESTORE = CS->CTL0 & CS_CTL0_DCORSEL_MASK;
/* set parameters for flashing */
success = MAP_PCM_SET_POWER_STATE(PCM_AM_LDO_VCORE0);
/* Set Flash wait states to 2 */
MAP_FLASH_CTL_A_SET_WAIT_STATE(FLASH_A_BANK0, 2);
MAP_FLASH_CTL_A_SET_WAIT_STATE(FLASH_A_BANK1, 2);
/* Set CPU speed to 24MHz */
__cs_set_dco_frequency_range(CS_DCO_FREQUENCY_24);
if (!success) {
/* Indicate failed power switch */
FLASH_LOADER->RETURN_CODE = FLASH_POWER_ERROR;
} else
FLASH_LOADER->RETURN_CODE = FLASH_SUCCESS;
}
/* Erase entire flash */
void msp432_flash_mass_erase(void)
{
bool success = false;
/* Allow flash writes */
unlock_flash_sectors();
/* Allow some mass erase repeats before timeout with error */
int erase_repeats = FLASH_MAX_REPEATS;
while (!success && (erase_repeats > 0)) {
/* Mass erase with post-verify */
success = ROM_FLASH_CTL_A_PERFORM_MASS_ERASE();
erase_repeats--;
}
if (erase_repeats == 0)
FLASH_LOADER->RETURN_CODE = FLASH_VERIFY_ERROR;
else
FLASH_LOADER->RETURN_CODE = FLASH_SUCCESS;
/* Block flash writes */
lock_all_flash_sectors();
}
/* Erase one flash sector */
void msp432_flash_sector_erase(void)
{
bool success = false;
/* Allow flash writes */
unlock_all_flash_sectors();
/* Allow some sector erase repeats before timeout with error */
int erase_repeats = FLASH_MAX_REPEATS;
while (!success && (erase_repeats > 0)) {
/* Sector erase with post-verify */
success = MAP_FLASH_CTL_A_ERASE_SECTOR(FLASH_LOADER->DST_ADDRESS);
erase_repeats--;
}
if (erase_repeats == 0)
FLASH_LOADER->RETURN_CODE = FLASH_ERROR;
else
FLASH_LOADER->RETURN_CODE = FLASH_SUCCESS;
/* Block flash writes */
lock_all_flash_sectors();
}
/* Write data to flash with the help of DriverLib */
void msp432_flash_write(void)
{
bool success = false;
/* Allow flash writes */
unlock_all_flash_sectors();
while (!(FLASH_LOADER->BUFFER1_STATUS_REGISTER & BUFFER_DATA_READY))
;
FLASH_LOADER->BUFFER1_STATUS_REGISTER |= BUFFER_ACTIVE;
/* Program memory */
success = program_device((uint32_t *)RAM_LOADER_BUFFER1,
(void *)FLASH_LOADER->DST_ADDRESS, FLASH_LOADER->SRC_LENGTH);
FLASH_LOADER->BUFFER1_STATUS_REGISTER &=
~(BUFFER_ACTIVE | BUFFER_DATA_READY);
/* Block flash writes */
lock_all_flash_sectors();
if (!success)
FLASH_LOADER->RETURN_CODE = FLASH_ERROR;
else
FLASH_LOADER->RETURN_CODE = FLASH_SUCCESS;
}
/* Write data to flash with the help of DriverLib with auto-increment */
void msp432_flash_continous_write(void)
{
bool buffer1_in_use = false;
bool buffer2_in_use = false;
uint32_t *src_address = NULL;
bool success = false;
uint32_t bytes_to_write = FLASH_LOADER->SRC_LENGTH;
uint32_t write_package = 0;
uint32_t start_addr = FLASH_LOADER->DST_ADDRESS;
while (bytes_to_write > 0) {
if (bytes_to_write > SRC_LENGTH_MAX) {
write_package = SRC_LENGTH_MAX;
bytes_to_write -= write_package;
} else {
write_package = bytes_to_write;
bytes_to_write -= write_package;
}
unlock_all_flash_sectors();
while (!(FLASH_LOADER->BUFFER1_STATUS_REGISTER & BUFFER_DATA_READY) &&
!(FLASH_LOADER->BUFFER2_STATUS_REGISTER & BUFFER_DATA_READY))
;
if (FLASH_LOADER->BUFFER1_STATUS_REGISTER & BUFFER_DATA_READY) {
FLASH_LOADER->BUFFER1_STATUS_REGISTER |= BUFFER_ACTIVE;
src_address = (uint32_t *) RAM_LOADER_BUFFER1;
buffer1_in_use = true;
} else if (FLASH_LOADER->BUFFER2_STATUS_REGISTER & BUFFER_DATA_READY) {
FLASH_LOADER->BUFFER2_STATUS_REGISTER |= BUFFER_ACTIVE;
src_address = (uint32_t *) RAM_LOADER_BUFFER2;
buffer2_in_use = true;
}
if (buffer1_in_use || buffer2_in_use) {
success = program_device(src_address, (void *) start_addr, write_package);
start_addr += write_package;
}
if (buffer1_in_use) {
FLASH_LOADER->BUFFER1_STATUS_REGISTER &= ~(BUFFER_ACTIVE | BUFFER_DATA_READY);
buffer1_in_use = false;
} else if (buffer2_in_use) {
FLASH_LOADER->BUFFER2_STATUS_REGISTER &= ~(BUFFER_ACTIVE | BUFFER_DATA_READY);
buffer2_in_use = false;
}
/* Block flash writes */
lock_all_flash_sectors();
if (!success) {
FLASH_LOADER->RETURN_CODE = FLASH_ERROR;
break;
}
}
if (success)
FLASH_LOADER->RETURN_CODE = FLASH_SUCCESS;
}
/* Unlock Main/Info Flash sectors */
void unlock_flash_sectors(void)
{
if (FLASH_LOADER->ERASE_PARAM & ERASE_MAIN)
MAP_FLASH_CTL_A_UNPROTECT_MEMORY(FLASH_BASE, FLASH_BASE +
MAP_SYS_CTL_A_GET_FLASH_SIZE() - 1);
if (FLASH_LOADER->ERASE_PARAM & ERASE_INFO) {
MAP_FLASH_CTL_A_UNPROTECT_MEMORY(INFO_FLASH_START, TLV_BASE - 1);
if (FLASH_LOADER->UNLOCK_BSL == UNLOCK_BSL_KEY)
MAP_FLASH_CTL_A_UNPROTECT_MEMORY(BSL_FLASH_START,
INFO_FLASH_MIDDLE - 1);
MAP_FLASH_CTL_A_UNPROTECT_MEMORY(INFO_FLASH_MIDDLE, INFO_FLASH_MIDDLE +
MAP_SYS_CTL_A_GET_INFO_FLASH_SIZE() - 1);
}
}
/* Unlock All Flash sectors */
void unlock_all_flash_sectors(void)
{
MAP_FLASH_CTL_A_UNPROTECT_MEMORY(FLASH_BASE, FLASH_BASE +
MAP_SYS_CTL_A_GET_FLASH_SIZE() - 1);
MAP_FLASH_CTL_A_UNPROTECT_MEMORY(INFO_FLASH_START, TLV_BASE - 1);
if (FLASH_LOADER->UNLOCK_BSL == UNLOCK_BSL_KEY)
MAP_FLASH_CTL_A_UNPROTECT_MEMORY(BSL_FLASH_START,
INFO_FLASH_MIDDLE - 1);
MAP_FLASH_CTL_A_UNPROTECT_MEMORY(INFO_FLASH_MIDDLE, INFO_FLASH_MIDDLE +
MAP_SYS_CTL_A_GET_INFO_FLASH_SIZE() - 1);
}
/* Lock all Flash sectors */
void lock_all_flash_sectors(void)
{
MAP_FLASH_CTL_A_PROTECT_MEMORY(FLASH_BASE, FLASH_BASE +
MAP_SYS_CTL_A_GET_FLASH_SIZE() - 1);
MAP_FLASH_CTL_A_PROTECT_MEMORY(INFO_FLASH_START, INFO_FLASH_START +
MAP_SYS_CTL_A_GET_INFO_FLASH_SIZE() - 1);
}
/* Force DCO frequency range */
void __cs_set_dco_frequency_range(uint32_t dco_freq)
{
/* Unlocking the CS Module */
CS->KEY = CS_KEY_VAL;
/* Resetting Tuning Parameters and Setting the frequency */
CS->CTL0 = (CS->CTL0 & ~CS_CTL0_DCORSEL_MASK) | dco_freq;
/* Locking the CS Module */
CS->KEY = 0;
}
/* Exit flash programming */
void msp432_flash_exit(void)
{
bool success = false;
/* Restore modified registers, in reverse order */
__cs_set_dco_frequency_range(CS_DCO_FREQUENCY_3);
MAP_FLASH_CTL_A_SET_WAIT_STATE(FLASH_A_BANK0,
BACKUP_PARAMS->BANK0_WAIT_RESTORE);
MAP_FLASH_CTL_A_SET_WAIT_STATE(FLASH_A_BANK1,
BACKUP_PARAMS->BANK1_WAIT_RESTORE);
success = MAP_PCM_SET_POWER_STATE(BACKUP_PARAMS->PCM_VCORE_LEVEL_RESTORE);
success &= MAP_PCM_SET_CORE_VOLTAGE_LEVEL(
BACKUP_PARAMS->VCORE_LEVEL_RESTORE);
__cs_set_dco_frequency_range(BACKUP_PARAMS->CS_DC0_FREQ_RESTORE);
/* Point to vector table in Flash */
SCB->VTOR = (uint32_t)0x00000000;
if (!success)
FLASH_LOADER->RETURN_CODE = FLASH_ERROR;
else
FLASH_LOADER->RETURN_CODE = FLASH_SUCCESS;
}
static bool program_device(void *src, void *dest, uint32_t length)
{
uint32_t dst_address = (uint32_t)dest;
/* Flash main memory first, then information memory */
if ((dst_address < INFO_FLASH_START) && ((dst_address + length) >
INFO_FLASH_START)) {
uint32_t block_length = INFO_FLASH_START - dst_address;
uint32_t src_address = (uint32_t)src;
/* Main memory block */
bool success = MAP_FLASH_CTL_A_PROGRAM_MEMORY(src, dest, block_length);
src_address = src_address + block_length;
block_length = length - block_length;
/* Information memory block */
success &= MAP_FLASH_CTL_A_PROGRAM_MEMORY((void *)src_address,
(void *)INFO_FLASH_START, block_length);
return success;
} else
return MAP_FLASH_CTL_A_PROGRAM_MEMORY(src, dest, length);
}

View File

@ -0,0 +1,229 @@
/******************************************************************************
*
* Copyright (C) 2017-2018 Texas Instruments Incorporated - http://www.ti.com/
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* distribution.
*
* Neither the name of Texas Instruments Incorporated nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************/
#ifndef OPENOCD_LOADERS_FLASH_MSP432_MSP432E4X_H
#define OPENOCD_LOADERS_FLASH_MSP432_MSP432E4X_H
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/* Register map for FLASH_CTRL peripheral (FLASH_CTRL) */
struct flash_ctrl {
volatile uint32_t FMA; /* Flash Memory Address */
volatile uint32_t FMD; /* Flash Memory Data */
volatile uint32_t FMC; /* Flash Memory Control */
volatile uint32_t FCRIS; /* Flash Controller Raw Interrupt Status */
volatile uint32_t FCIM; /* Flash Controller Interrupt Mask */
volatile uint32_t FCMISC; /* Flash Cont. Masked Int. Status and Clear */
volatile uint32_t RESERVED0[2];
volatile uint32_t FMC2; /* Flash Memory Control 2 */
volatile uint32_t RESERVED1[3];
volatile uint32_t FWBVAL; /* Flash Write Buffer Valid */
volatile uint32_t RESERVED2[2];
volatile uint32_t FLPEKEY; /* Flash Program/Erase Key */
volatile uint32_t RESERVED3[48];
volatile uint32_t FWBN[32]; /* Flash Write Buffer n */
};
/* Register map for SYSCTL peripheral (SYSCTL) */
struct sys_ctrl {
volatile uint32_t DID0; /* Device Identification 0 */
volatile uint32_t DID1; /* Device Identification 1 */
volatile uint32_t RESERVED0[12];
volatile uint32_t PTBOCTL; /* Power-Temp Brown Out Control */
volatile uint32_t RESERVED1[5];
volatile uint32_t RIS; /* Raw Interrupt Status */
volatile uint32_t IMC; /* Interrupt Mask Control */
volatile uint32_t MISC; /* Masked Interrupt Status and Clear */
volatile uint32_t RESC; /* Reset Cause */
volatile uint32_t PWRTC; /* Power-Temperature Cause */
volatile uint32_t NMIC; /* NMI Cause Register */
volatile uint32_t RESERVED2[5];
volatile uint32_t MOSCCTL; /* Main Oscillator Control */
volatile uint32_t RESERVED3[12];
volatile uint32_t RSCLKCFG; /* Run and Sleep Mode Configuration Register */
volatile uint32_t RESERVED4[3];
volatile uint32_t MEMTIM0; /* Memory Timing Register 0 for Main Flash */
volatile uint32_t RESERVED5[29];
volatile uint32_t ALTCLKCFG; /* Alternate Clock Configuration */
volatile uint32_t RESERVED6[2];
union {
volatile uint32_t DSLPCLKCFG; /* Deep Sleep Clock Configuration */
volatile uint32_t DSCLKCFG; /* Deep Sleep Clock Register */
};
volatile uint32_t DIVSCLK; /* Divisor and Source Clock Configuration */
volatile uint32_t SYSPROP; /* System Properties */
volatile uint32_t PIOSCCAL; /* Precision Internal Oscillator Calibration */
volatile uint32_t PIOSCSTAT; /* Precision Internal Oscillator Statistics */
volatile uint32_t RESERVED7[2];
volatile uint32_t PLLFREQ0; /* PLL Frequency 0 */
volatile uint32_t PLLFREQ1; /* PLL Frequency 1 */
volatile uint32_t PLLSTAT; /* PLL Status */
volatile uint32_t RESERVED8[7];
volatile uint32_t SLPPWRCFG; /* Sleep Power Configuration */
volatile uint32_t DSLPPWRCFG; /* Deep-Sleep Power Configuration */
volatile uint32_t RESERVED9[4];
volatile uint32_t NVMSTAT; /* Non-Volatile Memory Information */
volatile uint32_t RESERVED10[4];
volatile uint32_t LDOSPCTL; /* LDO Sleep Power Control */
volatile uint32_t RESERVED11;
volatile uint32_t LDODPCTL; /* LDO Deep-Sleep Power Control */
volatile uint32_t RESERVED12[6];
volatile uint32_t RESBEHAVCTL; /* Reset Behavior Control Register */
volatile uint32_t RESERVED13[6];
volatile uint32_t HSSR; /* Hardware System Service Request */
volatile uint32_t RESERVED14[34];
volatile uint32_t USBPDS; /* USB Power Domain Status */
volatile uint32_t USBMPC; /* USB Memory Power Control */
volatile uint32_t EMACPDS; /* Ethernet MAC Power Domain Status */
volatile uint32_t EMACMPC; /* Ethernet MAC Memory Power Control */
volatile uint32_t RESERVED15;
volatile uint32_t LCDMPC; /* LCD Memory Power Control */
volatile uint32_t RESERVED16[26];
volatile uint32_t PPWD; /* Watchdog Timer Peripheral Present */
volatile uint32_t PPTIMER; /* General-Purpose Timer Peripheral Present */
volatile uint32_t PPGPIO; /* General-Purpose I/O Peripheral Present */
volatile uint32_t PPDMA; /* Micro DMA Peripheral Present */
volatile uint32_t PPEPI; /* EPI Peripheral Present */
volatile uint32_t PPHIB; /* Hibernation Peripheral Present */
volatile uint32_t PPUART; /* UART Peripheral Present */
volatile uint32_t PPSSI; /* Synchronous Serial Inter. Periph. Present */
volatile uint32_t PPI2C; /* Inter-Integrated Circuit Periph. Present */
volatile uint32_t RESERVED17;
volatile uint32_t PPUSB; /* Universal Serial Bus Peripheral Present */
volatile uint32_t RESERVED18;
volatile uint32_t PPEPHY; /* Ethernet PHY Peripheral Present */
volatile uint32_t PPCAN; /* Controller Area Network Periph. Present */
volatile uint32_t PPADC; /* Analog-to-Dig. Converter Periph. Present */
volatile uint32_t PPACMP; /* Analog Comparator Peripheral Present */
volatile uint32_t PPPWM; /* Pulse Width Modulator Peripheral Present */
volatile uint32_t PPQEI; /* Quadrature Encoder Inter. Periph. Present */
volatile uint32_t RESERVED19[4];
volatile uint32_t PPEEPROM; /* EEPROM Peripheral Present */
volatile uint32_t RESERVED20[6];
volatile uint32_t PPCCM; /* CRC/Cryptographic Modules Periph. Present */
volatile uint32_t RESERVED21[6];
volatile uint32_t PPLCD; /* LCD Peripheral Present */
volatile uint32_t RESERVED22;
volatile uint32_t PPOWIRE; /* 1-Wire Peripheral Present */
volatile uint32_t PPEMAC; /* Ethernet MAC Peripheral Present */
volatile uint32_t RESERVED23[88];
volatile uint32_t SRWD; /* Watchdog Timer Software Reset */
volatile uint32_t SRTIMER; /* General-Purpose Timer Software Reset */
volatile uint32_t SRGPIO; /* General-Purpose I/O Software Reset */
volatile uint32_t SRDMA; /* Micro Direct Memory Access Software Reset */
volatile uint32_t SREPI; /* EPI Software Reset */
volatile uint32_t SRHIB; /* Hibernation Software Reset */
volatile uint32_t SRUART; /* UART Software Reset */
volatile uint32_t SRSSI; /* Synchronous Serial Inter. Software Reset */
volatile uint32_t SRI2C; /* Inter-Integrated Circuit Software Reset */
volatile uint32_t RESERVED24;
volatile uint32_t SRUSB; /* Universal Serial Bus Software Reset */
volatile uint32_t RESERVED25;
volatile uint32_t SREPHY; /* Ethernet PHY Software Reset */
volatile uint32_t SRCAN; /* Controller Area Network Software Reset */
volatile uint32_t SRADC; /* Analog-to-Dig. Converter Software Reset */
volatile uint32_t SRACMP; /* Analog Comparator Software Reset */
volatile uint32_t SRPWM; /* Pulse Width Modulator Software Reset */
volatile uint32_t SRQEI; /* Quadrature Encoder Inter. Software Reset */
volatile uint32_t RESERVED26[4];
volatile uint32_t SREEPROM; /* EEPROM Software Reset */
volatile uint32_t RESERVED27[6];
volatile uint32_t SRCCM; /* CRC/Cryptographic Modules Software Reset */
volatile uint32_t RESERVED28[6];
volatile uint32_t SRLCD; /* LCD Controller Software Reset */
volatile uint32_t RESERVED29;
volatile uint32_t SROWIRE; /* 1-Wire Software Reset */
volatile uint32_t SREMAC; /* Ethernet MAC Software Reset */
volatile uint32_t RESERVED30[24];
volatile uint32_t RCGCWD; /* Watchdog Run Mode Clock Gating Control */
};
/* Peripheral Memory Map */
#define FLASH_CTRL_BASE 0x400FD000UL
#define SYSCTL_BASE 0x400FE000UL
/* Peripheral Declarations */
#define FLASH_CTRL ((struct flash_ctrl *) FLASH_CTRL_BASE)
#define SYSCTL ((struct sys_ctrl *) SYSCTL_BASE)
/* The following are defines for the bit fields in the FLASH_FMC register. */
#define FLASH_FMC_WRKEY 0xA4420000 /* FLASH write key */
#define FLASH_FMC_COMT 0x00000008 /* Commit Register Value */
#define FLASH_FMC_MERASE 0x00000004 /* Mass Erase Flash Memory */
#define FLASH_FMC_ERASE 0x00000002 /* Erase a Page of Flash Memory */
#define FLASH_FMC_WRITE 0x00000001 /* Write a Word into Flash Memory */
/* The following are defines for the bit fields in the FLASH_FCRIS register. */
#define FLASH_FCRIS_PROGRIS 0x00002000 /* Program Verify Raw Interrupt Status */
#define FLASH_FCRIS_ERRIS 0x00000800 /* Erase Verify Raw Interrupt Status */
#define FLASH_FCRIS_INVDRIS 0x00000400 /* Invalid Data Raw Interrupt Status */
#define FLASH_FCRIS_VOLTRIS 0x00000200 /* Pump Voltage Raw Interrupt Status */
#define FLASH_FCRIS_ERIS 0x00000004 /* EEPROM Raw Interrupt Status */
#define FLASH_FCRIS_PRIS 0x00000002 /* Programming Raw Interrupt Status */
#define FLASH_FCRIS_ARIS 0x00000001 /* Access Raw Interrupt Status */
/* The following are defines for the bit fields in the FLASH_FCIM register. */
#define FLASH_FCIM_PROGMASK 0x00002000 /* PROGVER Interrupt Mask */
#define FLASH_FCIM_ERMASK 0x00000800 /* ERVER Interrupt Mask */
#define FLASH_FCIM_INVDMASK 0x00000400 /* Invalid Data Interrupt Mask */
#define FLASH_FCIM_VOLTMASK 0x00000200 /* VOLT Interrupt Mask */
#define FLASH_FCIM_EMASK 0x00000004 /* EEPROM Interrupt Mask */
#define FLASH_FCIM_PMASK 0x00000002 /* Programming Interrupt Mask */
#define FLASH_FCIM_AMASK 0x00000001 /* Access Interrupt Mask */
/* The following are defines for the bit fields in the FLASH_FCMISC register. */
#define FLASH_FCMISC_PROGMISC 0x00002000 /* PROGVER Interrupt Status/Clear */
#define FLASH_FCMISC_ERMISC 0x00000800 /* ERVER Interrupt Status/Clear */
#define FLASH_FCMISC_INVDMISC 0x00000400 /* Invalid Data Int. Status/Clear */
#define FLASH_FCMISC_VOLTMISC 0x00000200 /* VOLT Interrupt Status/Clear */
#define FLASH_FCMISC_EMISC 0x00000004 /* EEPROM Interrupt Status/Clear */
#define FLASH_FCMISC_PMISC 0x00000002 /* Programming Int. Status/Clear */
#define FLASH_FCMISC_AMISC 0x00000001 /* Access Interrupt Status/Clear */
/* The following are defines for the bit fields in the FLASH_FMC2 register. */
#define FLASH_FMC2_WRBUF 0x00000001 /* Buffered Flash Memory Write */
/* The following are defines for the bit fields in the SYSCTL_RCGCWD reg. */
#define SYSCTL_RCGCWD_R1 0x00000002 /* Watchdog 1 Run Mode Clock Gating Cont. */
#define SYSCTL_RCGCWD_R0 0x00000001 /* Watchdog 0 Run Mode Clock Gating Cont. */
#ifdef __cplusplus
}
#endif
#endif /* OPENOCD_LOADERS_FLASH_MSP432_MSP432E4X_H */

View File

@ -0,0 +1,149 @@
/******************************************************************************
*
* Copyright (C) 2017-2018 Texas Instruments Incorporated - http://www.ti.com/
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* distribution.
*
* Neither the name of Texas Instruments Incorporated nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************/
MEMORY {
MAIN_FLASH (RX) : ORIGIN = 0x00000000, LENGTH = 0x00100000
SRAM_CODE_0(RWX): ORIGIN = 0x20000000, LENGTH = 0x00000110
SRAM_CODE_1(RWX): ORIGIN = 0x20000110, LENGTH = 0x00000030
SRAM_CODE_2(RWX): ORIGIN = 0x20000150, LENGTH = 0x00000040
SRAM_CODE_3(RWX): ORIGIN = 0x20000190, LENGTH = 0x00000F70
SRAM_CODE_4(RWX): ORIGIN = 0x20001170, LENGTH = 0x00000200
SRAM_DATA (RW) : ORIGIN = 0x20002000, LENGTH = 0x00001000
}
REGION_ALIAS("REGION_INTVECT", SRAM_CODE_0);
REGION_ALIAS("REGION_RESET", SRAM_CODE_1);
REGION_ALIAS("REGION_DESCRIPTOR", SRAM_CODE_2);
REGION_ALIAS("REGION_TEXT", SRAM_CODE_3);
REGION_ALIAS("REGION_BSS", SRAM_CODE_3);
REGION_ALIAS("REGION_DATA", SRAM_DATA);
REGION_ALIAS("REGION_STACK", SRAM_CODE_4);
REGION_ALIAS("REGION_HEAP", SRAM_DATA);
REGION_ALIAS("REGION_ARM_EXIDX", SRAM_CODE_3);
REGION_ALIAS("REGION_ARM_EXTAB", SRAM_CODE_3);
SECTIONS {
/* section for the interrupt vector area */
.intvecs : {
KEEP (*(.intvecs))
} > REGION_INTVECT
PROVIDE (_vtable_base_address =
DEFINED(_vtable_base_address) ? _vtable_base_address : 0x20000000);
.vtable (_vtable_base_address) : AT (_vtable_base_address) {
KEEP (*(.vtable))
} > REGION_DATA
.descriptor :{
FILL(0x00000000);
. = ORIGIN(REGION_DESCRIPTOR) + LENGTH(REGION_DESCRIPTOR) - 1;
BYTE(0x00);
__ROM_AT = .;
} > REGION_DESCRIPTOR
.reset : {
KEEP(*(.reset))
} > REGION_RESET AT> REGION_RESET
.text : {
CREATE_OBJECT_SYMBOLS
KEEP (*(.text))
*(.text.*)
. = ALIGN(0x4);
KEEP (*(.ctors))
. = ALIGN(0x4);
KEEP (*(.dtors))
. = ALIGN(0x4);
__init_array_start = .;
KEEP (*(.init_array*))
__init_array_end = .;
KEEP (*(.init))
KEEP (*(.fini*))
} > REGION_TEXT AT> REGION_TEXT
.rodata : {
*(.rodata)
*(.rodata.*)
} > REGION_TEXT AT> REGION_TEXT
.ARM.exidx : {
__exidx_start = .;
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
__exidx_end = .;
} > REGION_ARM_EXIDX AT> REGION_ARM_EXIDX
.ARM.extab : {
KEEP (*(.ARM.extab* .gnu.linkonce.armextab.*))
} > REGION_ARM_EXTAB AT> REGION_ARM_EXTAB
__etext = .;
.data : {
__data_load__ = LOADADDR (.data);
__data_start__ = .;
KEEP (*(.data))
KEEP (*(.data*))
. = ALIGN (4);
__data_end__ = .;
} > REGION_DATA AT> REGION_TEXT
.bss : {
__bss_start__ = .;
*(.shbss)
KEEP (*(.bss))
*(.bss.*)
*(COMMON)
. = ALIGN (4);
__bss_end__ = .;
} > REGION_BSS AT> REGION_BSS
.heap : {
__heap_start__ = .;
end = __heap_start__;
_end = end;
__end = end;
KEEP (*(.heap))
__heap_end__ = .;
__HeapLimit = __heap_end__;
} > REGION_HEAP AT> REGION_HEAP
.stack (NOLOAD) : ALIGN(0x8) {
_stack = .;
KEEP(*(.stack))
} > REGION_STACK AT> REGION_STACK
__stack_top = ORIGIN(REGION_STACK) + LENGTH(REGION_STACK);
PROVIDE(__stack = __stack_top);
}

View File

@ -0,0 +1,245 @@
/* Autogenerated with ../../../../src/helper/bin2char.sh */
0x70,0x13,0x00,0x20,0x11,0x01,0x00,0x20,0xc9,0x0a,0x00,0x20,0xc9,0x0a,0x00,0x20,
0xc9,0x0a,0x00,0x20,0xc9,0x0a,0x00,0x20,0xc9,0x0a,0x00,0x20,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc9,0x0a,0x00,0x20,
0xc9,0x0a,0x00,0x20,0x00,0x00,0x00,0x00,0xc9,0x0a,0x00,0x20,0xc9,0x0a,0x00,0x20,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x41,0xf2,0x00,0x70,0xc2,0xf2,0x00,0x00,0x85,0x46,0x05,0x48,0x05,0x49,0x4f,0xf0,
0x00,0x02,0x88,0x42,0xb8,0xbf,0x40,0xf8,0x04,0x2b,0xfa,0xdb,0x00,0xf0,0x16,0xbc,
0x34,0x0f,0x00,0x20,0x50,0x0f,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x04,0x4b,0x05,0x48,0x1b,0x1a,0x06,0x2b,0x02,0xd9,0x04,0x4b,0x03,0xb1,0x18,0x47,
0x70,0x47,0x00,0xbf,0x37,0x24,0x00,0x20,0x34,0x24,0x00,0x20,0x00,0x00,0x00,0x00,
0x05,0x49,0x06,0x48,0x09,0x1a,0x89,0x10,0x01,0xeb,0xd1,0x71,0x49,0x10,0x02,0xd0,
0x03,0x4b,0x03,0xb1,0x18,0x47,0x70,0x47,0x34,0x24,0x00,0x20,0x34,0x24,0x00,0x20,
0x00,0x00,0x00,0x00,0x10,0xb5,0x06,0x4c,0x23,0x78,0x43,0xb9,0xff,0xf7,0xd8,0xff,
0x04,0x4b,0x13,0xb1,0x04,0x48,0xaf,0xf3,0x00,0x80,0x01,0x23,0x23,0x70,0x10,0xbd,
0x34,0x0f,0x00,0x20,0x00,0x00,0x00,0x00,0xf8,0x0a,0x00,0x20,0x08,0xb5,0x08,0x4b,
0x1b,0xb1,0x08,0x48,0x08,0x49,0xaf,0xf3,0x00,0x80,0x08,0x48,0x03,0x68,0x13,0xb9,
0xbd,0xe8,0x08,0x40,0xcc,0xe7,0x06,0x4b,0x00,0x2b,0xf9,0xd0,0x98,0x47,0xf7,0xe7,
0x00,0x00,0x00,0x00,0xf8,0x0a,0x00,0x20,0x38,0x0f,0x00,0x20,0x34,0x24,0x00,0x20,
0x00,0x00,0x00,0x00,0x13,0x4b,0x00,0x2b,0x08,0xbf,0x11,0x4b,0x9d,0x46,0xa3,0xf5,
0x80,0x3a,0x00,0x21,0x8b,0x46,0x0f,0x46,0x11,0x48,0x12,0x4a,0x12,0x1a,0x00,0xf0,
0x13,0xf9,0x0d,0x4b,0x00,0x2b,0x00,0xd0,0x98,0x47,0x0c,0x4b,0x00,0x2b,0x00,0xd0,
0x98,0x47,0x00,0x20,0x00,0x21,0x04,0x00,0x0d,0x00,0x0b,0x48,0x00,0xf0,0xb0,0xf8,
0x00,0xf0,0xda,0xf8,0x20,0x00,0x29,0x00,0x00,0xf0,0x70,0xfb,0x00,0xf0,0xae,0xf8,
0x00,0x00,0x08,0x00,0x70,0x13,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x34,0x0f,0x00,0x20,0x50,0x0f,0x00,0x20,0xfd,0x03,0x00,0x20,0x84,0x46,0x41,0xea,
0x00,0x03,0x13,0xf0,0x03,0x03,0x6d,0xd1,0x40,0x3a,0x41,0xd3,0x51,0xf8,0x04,0x3b,
0x40,0xf8,0x04,0x3b,0x51,0xf8,0x04,0x3b,0x40,0xf8,0x04,0x3b,0x51,0xf8,0x04,0x3b,
0x40,0xf8,0x04,0x3b,0x51,0xf8,0x04,0x3b,0x40,0xf8,0x04,0x3b,0x51,0xf8,0x04,0x3b,
0x40,0xf8,0x04,0x3b,0x51,0xf8,0x04,0x3b,0x40,0xf8,0x04,0x3b,0x51,0xf8,0x04,0x3b,
0x40,0xf8,0x04,0x3b,0x51,0xf8,0x04,0x3b,0x40,0xf8,0x04,0x3b,0x51,0xf8,0x04,0x3b,
0x40,0xf8,0x04,0x3b,0x51,0xf8,0x04,0x3b,0x40,0xf8,0x04,0x3b,0x51,0xf8,0x04,0x3b,
0x40,0xf8,0x04,0x3b,0x51,0xf8,0x04,0x3b,0x40,0xf8,0x04,0x3b,0x51,0xf8,0x04,0x3b,
0x40,0xf8,0x04,0x3b,0x51,0xf8,0x04,0x3b,0x40,0xf8,0x04,0x3b,0x51,0xf8,0x04,0x3b,
0x40,0xf8,0x04,0x3b,0x51,0xf8,0x04,0x3b,0x40,0xf8,0x04,0x3b,0x40,0x3a,0xbd,0xd2,
0x30,0x32,0x11,0xd3,0x51,0xf8,0x04,0x3b,0x40,0xf8,0x04,0x3b,0x51,0xf8,0x04,0x3b,
0x40,0xf8,0x04,0x3b,0x51,0xf8,0x04,0x3b,0x40,0xf8,0x04,0x3b,0x51,0xf8,0x04,0x3b,
0x40,0xf8,0x04,0x3b,0x10,0x3a,0xed,0xd2,0x0c,0x32,0x05,0xd3,0x51,0xf8,0x04,0x3b,
0x40,0xf8,0x04,0x3b,0x04,0x3a,0xf9,0xd2,0x04,0x32,0x08,0xd0,0xd2,0x07,0x1c,0xbf,
0x11,0xf8,0x01,0x3b,0x00,0xf8,0x01,0x3b,0x01,0xd3,0x0b,0x88,0x03,0x80,0x60,0x46,
0x70,0x47,0x00,0xbf,0x08,0x2a,0x13,0xd3,0x8b,0x07,0x8d,0xd0,0x10,0xf0,0x03,0x03,
0x8a,0xd0,0xc3,0xf1,0x04,0x03,0xd2,0x1a,0xdb,0x07,0x1c,0xbf,0x11,0xf8,0x01,0x3b,
0x00,0xf8,0x01,0x3b,0x80,0xd3,0x31,0xf8,0x02,0x3b,0x20,0xf8,0x02,0x3b,0x7b,0xe7,
0x04,0x3a,0xd9,0xd3,0x01,0x3a,0x11,0xf8,0x01,0x3b,0x00,0xf8,0x01,0x3b,0xf9,0xd2,
0x0b,0x78,0x03,0x70,0x4b,0x78,0x43,0x70,0x8b,0x78,0x83,0x70,0x60,0x46,0x70,0x47,
0x01,0x46,0x00,0x20,0x02,0x46,0x03,0x46,0x00,0xf0,0x9c,0xb8,0x08,0xb5,0x00,0x21,
0x04,0x46,0x00,0xf0,0xf3,0xf8,0x04,0x4b,0x18,0x68,0xc3,0x6b,0x03,0xb1,0x98,0x47,
0x20,0x46,0x00,0xf0,0x55,0xf9,0x00,0xbf,0xf4,0x0a,0x00,0x20,0x38,0xb5,0x08,0x4b,
0x08,0x4d,0xed,0x1a,0xac,0x10,0x18,0xbf,0xed,0x18,0x05,0xd0,0x01,0x3c,0x55,0xf8,
0x04,0x3d,0x98,0x47,0x00,0x2c,0xf9,0xd1,0xbd,0xe8,0x38,0x40,0x00,0xf0,0x60,0xbb,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x70,0xb5,0x0f,0x4e,0x0f,0x4d,0x76,0x1b,
0xb6,0x10,0x18,0xbf,0x00,0x24,0x05,0xd0,0x01,0x34,0x55,0xf8,0x04,0x3b,0x98,0x47,
0xa6,0x42,0xf9,0xd1,0x0a,0x4e,0x0b,0x4d,0x76,0x1b,0x00,0xf0,0x43,0xfb,0xb6,0x10,
0x18,0xbf,0x00,0x24,0x06,0xd0,0x01,0x34,0x55,0xf8,0x04,0x3b,0x98,0x47,0xa6,0x42,
0xf9,0xd1,0x70,0xbd,0x70,0xbd,0x00,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0xd4,0x0a,0x00,0x20,0xcc,0x0a,0x00,0x20,0x70,0xb4,0x84,0x07,0x46,0xd0,0x54,0x1e,
0x00,0x2a,0x41,0xd0,0xcd,0xb2,0x03,0x46,0x02,0xe0,0x62,0x1e,0xe4,0xb3,0x14,0x46,
0x03,0xf8,0x01,0x5b,0x9a,0x07,0xf8,0xd1,0x03,0x2c,0x2e,0xd9,0xcd,0xb2,0x45,0xea,
0x05,0x25,0x0f,0x2c,0x45,0xea,0x05,0x45,0x19,0xd9,0x03,0xf1,0x10,0x02,0x26,0x46,
0x10,0x3e,0x0f,0x2e,0x42,0xf8,0x10,0x5c,0x42,0xf8,0x0c,0x5c,0x42,0xf8,0x08,0x5c,
0x42,0xf8,0x04,0x5c,0x02,0xf1,0x10,0x02,0xf2,0xd8,0xa4,0xf1,0x10,0x02,0x22,0xf0,
0x0f,0x02,0x04,0xf0,0x0f,0x04,0x10,0x32,0x03,0x2c,0x13,0x44,0x0d,0xd9,0x1e,0x46,
0x22,0x46,0x04,0x3a,0x03,0x2a,0x46,0xf8,0x04,0x5b,0xfa,0xd8,0x22,0x1f,0x22,0xf0,
0x03,0x02,0x04,0x32,0x13,0x44,0x04,0xf0,0x03,0x04,0x2c,0xb1,0xc9,0xb2,0x1c,0x44,
0x03,0xf8,0x01,0x1b,0xa3,0x42,0xfb,0xd1,0x70,0xbc,0x70,0x47,0x14,0x46,0x03,0x46,
0xc2,0xe7,0x00,0xbf,0x2d,0xe9,0xf0,0x47,0x25,0x4c,0x25,0x68,0xd5,0xf8,0x48,0x41,
0x06,0x46,0x88,0x46,0x92,0x46,0x99,0x46,0xcc,0xb3,0x60,0x68,0x1f,0x28,0x18,0xdc,
0x43,0x1c,0x7e,0xb1,0x04,0xeb,0x80,0x05,0x01,0x21,0xc5,0xf8,0x88,0xa0,0xd4,0xf8,
0x88,0x71,0x01,0xfa,0x00,0xf2,0x17,0x43,0x02,0x2e,0xc4,0xf8,0x88,0x71,0xc5,0xf8,
0x08,0x91,0x1e,0xd0,0x02,0x30,0x63,0x60,0x44,0xf8,0x20,0x80,0x00,0x20,0xbd,0xe8,
0xf0,0x87,0x14,0x4b,0x03,0xb3,0x4f,0xf4,0xc8,0x70,0xaf,0xf3,0x00,0x80,0x04,0x46,
0xd0,0xb1,0xd5,0xf8,0x48,0x31,0x00,0x27,0x80,0xe8,0x88,0x00,0xc5,0xf8,0x48,0x41,
0x38,0x46,0x01,0x23,0xc4,0xf8,0x88,0x71,0xc4,0xf8,0x8c,0x71,0x00,0x2e,0xe1,0xd0,
0xd0,0xe7,0xd4,0xf8,0x8c,0x11,0x0a,0x43,0xc4,0xf8,0x8c,0x21,0xda,0xe7,0x05,0xf5,
0xa6,0x74,0xc5,0xf8,0x48,0x41,0xc0,0xe7,0x4f,0xf0,0xff,0x30,0xbd,0xe8,0xf0,0x87,
0xf4,0x0a,0x00,0x20,0x00,0x00,0x00,0x00,0x02,0x4b,0x13,0xb1,0x02,0x48,0xff,0xf7,
0x07,0xbf,0x70,0x47,0x00,0x00,0x00,0x00,0xfd,0x03,0x00,0x20,0x2d,0xe9,0xf0,0x4f,
0x31,0x4b,0x83,0xb0,0x1b,0x68,0x00,0x93,0x03,0xf5,0xa4,0x73,0x81,0x46,0x0e,0x46,
0x01,0x93,0x00,0x9b,0xd3,0xf8,0x48,0x71,0x27,0xb3,0xdd,0xf8,0x04,0xa0,0x7c,0x68,
0x65,0x1e,0x0e,0xd4,0x01,0x34,0x07,0xeb,0x84,0x04,0x4f,0xf0,0x00,0x08,0xe6,0xb1,
0xd4,0xf8,0x00,0x31,0xb3,0x42,0x18,0xd0,0x01,0x3d,0x6b,0x1c,0xa4,0xf1,0x04,0x04,
0xf5,0xd1,0x22,0x4b,0x73,0xb1,0x7b,0x68,0x00,0x2b,0x36,0xd1,0x3b,0x68,0x00,0x2b,
0x34,0xd0,0x38,0x46,0xca,0xf8,0x00,0x30,0xaf,0xf3,0x00,0x80,0xda,0xf8,0x00,0x70,
0x00,0x2f,0xdc,0xd1,0x03,0xb0,0xbd,0xe8,0xf0,0x8f,0x7b,0x68,0x22,0x68,0x01,0x3b,
0xab,0x42,0x0c,0xbf,0x7d,0x60,0xc4,0xf8,0x00,0x80,0x00,0x2a,0xdc,0xd0,0xd7,0xf8,
0x88,0x31,0xd7,0xf8,0x04,0xb0,0x01,0x21,0xa9,0x40,0x19,0x42,0x08,0xd1,0x90,0x47,
0x7b,0x68,0x5b,0x45,0xbd,0xd1,0xda,0xf8,0x00,0x30,0xbb,0x42,0xcc,0xd0,0xb8,0xe7,
0xd7,0xf8,0x8c,0x31,0x19,0x42,0x04,0xd1,0x48,0x46,0xd4,0xf8,0x80,0x10,0x90,0x47,
0xee,0xe7,0xd4,0xf8,0x80,0x00,0x90,0x47,0xea,0xe7,0x3b,0x68,0xba,0x46,0x1f,0x46,
0x00,0x2f,0xac,0xd1,0xce,0xe7,0x00,0xbf,0xf4,0x0a,0x00,0x20,0x00,0x00,0x00,0x00,
0xfe,0xe7,0x00,0xbf,0x2d,0xe9,0xf0,0x4f,0xa8,0x4b,0xa9,0x4a,0xde,0x68,0xd3,0xf8,
0x10,0xb0,0x85,0xb0,0x42,0xf2,0x03,0x61,0x00,0x24,0x99,0x46,0xa5,0x4b,0x51,0x61,
0x15,0x46,0x90,0x46,0x00,0x94,0xbb,0xf5,0x80,0x5f,0x93,0xbf,0x5f,0x46,0xab,0xf5,
0x80,0x5b,0x4f,0xf4,0x80,0x57,0x4f,0xf0,0x00,0x0b,0x03,0xe0,0xd9,0xf8,0x18,0x20,
0xd2,0x06,0x03,0xd4,0xd9,0xf8,0x14,0x20,0xd1,0x06,0xf7,0xd5,0xd9,0xf8,0x14,0x20,
0x12,0xf0,0x10,0x02,0x00,0xf0,0xb9,0x80,0xd9,0xf8,0x14,0x20,0x42,0xf0,0x01,0x02,
0xc9,0xf8,0x14,0x20,0x4f,0xf0,0x20,0x24,0x4f,0xf0,0x01,0x0a,0x16,0xf0,0x03,0x02,
0x00,0xf0,0xa9,0x80,0x26,0xf0,0x03,0x0c,0xdc,0xf8,0x00,0x10,0x03,0x91,0x47,0xb3,
0x21,0x46,0x78,0x1e,0x11,0xf8,0x01,0xeb,0x01,0x91,0x04,0xa9,0x11,0x44,0x01,0xf8,
0x04,0xec,0x02,0xf1,0x01,0x01,0x06,0xf1,0x01,0x0e,0x00,0xf0,0x01,0x81,0x04,0x29,
0x00,0xf0,0xfe,0x80,0x04,0xa8,0x01,0x44,0x60,0x78,0x01,0xf8,0x04,0x0c,0xb9,0x1e,
0x00,0x29,0x06,0xf1,0x02,0x00,0x04,0xf1,0x02,0x0e,0x40,0xf3,0xec,0x80,0x01,0x2a,
0x40,0xf0,0xe9,0x80,0xa2,0x78,0x8d,0xf8,0x0f,0x20,0x03,0x99,0x03,0x36,0x03,0x3f,
0x03,0x34,0x78,0x4a,0x69,0x60,0xc5,0xf8,0x00,0xc0,0xaa,0x60,0xaa,0x68,0xd0,0x07,
0xfc,0xd4,0xd8,0xf8,0x0c,0x10,0x42,0xf2,0x05,0x42,0x0a,0x40,0xb2,0xfa,0x82,0xf2,
0x52,0x09,0x03,0x2f,0x1a,0xdd,0x71,0x06,0x79,0xd0,0x00,0x2a,0x75,0xd0,0x54,0xf8,
0x04,0x2b,0x6a,0x60,0x2e,0x60,0xab,0x60,0xaa,0x68,0xd2,0x07,0xfc,0xd4,0xd8,0xf8,
0x0c,0x10,0x04,0x3f,0x42,0xf2,0x05,0x42,0x03,0x2f,0x02,0xea,0x01,0x02,0x06,0xf1,
0x04,0x06,0xb2,0xfa,0x82,0xf2,0x4f,0xea,0x52,0x12,0xe4,0xdc,0x00,0x2f,0x15,0xdc,
0xba,0xf1,0x00,0x0f,0x33,0xd0,0xd9,0xf8,0x14,0x10,0x21,0xf0,0x11,0x01,0xc9,0xf8,
0x14,0x10,0x00,0x2a,0x38,0xd0,0xbb,0xf1,0x00,0x0f,0x7f,0xf4,0x6c,0xaf,0x57,0x4b,
0x40,0xf6,0xce,0x22,0x5a,0x60,0x05,0xb0,0xbd,0xe8,0xf0,0x8f,0x00,0x2a,0xe7,0xd0,
0x04,0xa8,0x32,0x68,0x40,0xf8,0x04,0x2d,0x21,0x46,0x3a,0x46,0x01,0x93,0xff,0xf7,
0x45,0xfd,0x03,0x9a,0x4f,0x4b,0x6a,0x60,0x2e,0x60,0xab,0x60,0x01,0x9b,0x37,0x44,
0xaa,0x68,0xd2,0x07,0xfc,0xd4,0xd8,0xf8,0x0c,0x10,0x42,0xf2,0x05,0x42,0x0a,0x40,
0x3e,0x46,0xb2,0xfa,0x82,0xf2,0x52,0x09,0xba,0xf1,0x00,0x0f,0xcb,0xd1,0x00,0x99,
0x00,0x29,0xce,0xd0,0xd9,0xf8,0x18,0x10,0xcd,0xf8,0x00,0xa0,0x21,0xf0,0x11,0x01,
0xc9,0xf8,0x18,0x10,0x00,0x2a,0xc6,0xd1,0x3c,0x4b,0x4d,0xf6,0xad,0x62,0x5a,0x60,
0x05,0xb0,0xbd,0xe8,0xf0,0x8f,0x01,0x22,0x93,0xe7,0xd9,0xf8,0x18,0x10,0x11,0xf0,
0x10,0x01,0x5e,0xd0,0xd9,0xf8,0x18,0x10,0x37,0x4c,0x41,0xf0,0x01,0x01,0x92,0x46,
0x01,0x22,0xc9,0xf8,0x18,0x10,0x00,0x92,0x40,0xe7,0x00,0x22,0xa0,0xe7,0x1f,0x2f,
0x32,0xdd,0x00,0x2a,0xf9,0xd0,0x07,0xf1,0xff,0x3e,0x2e,0xf0,0x03,0x0e,0x0e,0xf1,
0x04,0x0e,0xa6,0x44,0x39,0x46,0x04,0xf1,0x80,0x0c,0x00,0x22,0x01,0xe0,0x64,0x45,
0x0b,0xd0,0x54,0xf8,0x04,0x7b,0x02,0xf1,0x40,0x00,0x74,0x45,0xa1,0xf1,0x04,0x01,
0x45,0xf8,0x20,0x70,0x02,0xf1,0x01,0x02,0xf1,0xd1,0x2e,0x60,0x0f,0x46,0x2b,0x62,
0x2a,0x6a,0xd0,0x07,0xfc,0xd4,0xd8,0xf8,0x0c,0x00,0x42,0xf2,0x05,0x42,0x1f,0x29,
0x02,0xea,0x00,0x02,0x06,0xf1,0x80,0x06,0xb2,0xfa,0x82,0xf2,0x4f,0xea,0x52,0x12,
0xcf,0xdc,0x03,0x29,0x7f,0xf7,0x6a,0xaf,0x00,0x2a,0xc6,0xd0,0x54,0xf8,0x04,0x2b,
0x6a,0x60,0x2e,0x60,0xab,0x60,0xaa,0x68,0xd1,0x07,0xfc,0xd4,0xd8,0xf8,0x0c,0x10,
0x04,0x3f,0x42,0xf2,0x05,0x42,0x03,0x2f,0x02,0xea,0x01,0x02,0x06,0xf1,0x04,0x06,
0xb2,0xfa,0x82,0xf2,0x4f,0xea,0x52,0x12,0xe6,0xdc,0x00,0x2f,0x7f,0xf7,0x50,0xaf,
0x64,0xe7,0x8a,0x46,0xea,0xe6,0x0f,0x46,0x74,0x46,0x06,0x46,0x03,0x99,0x18,0xe7,
0x01,0x9c,0x03,0x99,0x07,0x46,0x76,0x46,0x13,0xe7,0x00,0xbf,0x50,0x01,0x00,0x20,
0x00,0xd0,0x0f,0x40,0x01,0x00,0x42,0xa4,0x00,0x30,0x00,0x20,0x80,0xb5,0x72,0xb6,
0x52,0x4a,0x53,0x4c,0xd2,0xf8,0x00,0x36,0x52,0x4d,0x53,0x4f,0x53,0x4e,0x23,0xf0,
0x03,0x03,0xc2,0xf8,0x00,0x36,0xa0,0x46,0x2b,0x68,0x20,0x2b,0x00,0xf2,0x8d,0x80,
0x01,0xa2,0x52,0xf8,0x23,0xf0,0x00,0xbf,0x79,0x09,0x00,0x20,0x75,0x0a,0x00,0x20,
0x4b,0x0a,0x00,0x20,0x9b,0x0a,0x00,0x20,0x3d,0x0a,0x00,0x20,0x9b,0x0a,0x00,0x20,
0x9b,0x0a,0x00,0x20,0x9b,0x0a,0x00,0x20,0x21,0x0a,0x00,0x20,0x9b,0x0a,0x00,0x20,
0x9b,0x0a,0x00,0x20,0x9b,0x0a,0x00,0x20,0x9b,0x0a,0x00,0x20,0x9b,0x0a,0x00,0x20,
0x9b,0x0a,0x00,0x20,0x9b,0x0a,0x00,0x20,0x0d,0x0a,0x00,0x20,0x9b,0x0a,0x00,0x20,
0x9b,0x0a,0x00,0x20,0x9b,0x0a,0x00,0x20,0x9b,0x0a,0x00,0x20,0x9b,0x0a,0x00,0x20,
0x9b,0x0a,0x00,0x20,0x9b,0x0a,0x00,0x20,0x9b,0x0a,0x00,0x20,0x9b,0x0a,0x00,0x20,
0x9b,0x0a,0x00,0x20,0x9b,0x0a,0x00,0x20,0x9b,0x0a,0x00,0x20,0x9b,0x0a,0x00,0x20,
0x9b,0x0a,0x00,0x20,0x9b,0x0a,0x00,0x20,0x3d,0x0a,0x00,0x20,0x2c,0x49,0x00,0x23,
0x01,0x20,0x40,0xf6,0xce,0x22,0x68,0x60,0x8b,0x60,0x6a,0x60,0x2b,0x60,0xab,0xe7,
0x27,0x49,0x4f,0xf0,0x01,0x0e,0x4f,0xf0,0x00,0x50,0x40,0xf6,0xce,0x22,0x00,0x23,
0xc5,0xf8,0x04,0xe0,0x88,0x60,0x6a,0x60,0x2b,0x60,0x9d,0xe7,0x01,0x23,0x6b,0x60,
0xff,0xf7,0x30,0xfe,0x00,0x23,0x2b,0x60,0x96,0xe7,0x40,0xf6,0x03,0x23,0x01,0x22,
0x6a,0x60,0x63,0x61,0xeb,0x68,0x23,0x60,0xa7,0x60,0xa3,0x68,0x9b,0x07,0xfc,0xd4,
0xd8,0xf8,0x0c,0x20,0x40,0xf6,0x01,0x23,0x13,0x40,0xd3,0xb9,0x40,0xf6,0xce,0x23,
0x6b,0x60,0xe7,0xe7,0x01,0x22,0x40,0xf6,0x03,0x23,0x6a,0x60,0x63,0x61,0xa6,0x60,
0xa3,0x68,0x5a,0x07,0xfc,0xd4,0xd8,0xf8,0x0c,0x20,0x40,0xf6,0x01,0x23,0x13,0x40,
0x00,0x2b,0xeb,0xd0,0x0b,0x4b,0x6b,0x60,0xd4,0xe7,0x40,0xf6,0xad,0x33,0x6b,0x60,
0x6a,0xe7,0x4d,0xf6,0xad,0x63,0x6b,0x60,0xcc,0xe7,0x00,0xbf,0x00,0xe0,0x0f,0x40,
0x00,0xd0,0x0f,0x40,0x50,0x01,0x00,0x20,0x02,0x00,0x42,0xa4,0x04,0x00,0x42,0xa4,
0x00,0xed,0x00,0xe0,0xad,0xde,0xad,0xde,0xfe,0xe7,0x00,0xbf,0xfd,0x01,0x00,0x20,
0xb9,0x05,0x00,0x20,0xf8,0xb5,0x00,0xbf,0xf8,0xbc,0x08,0xbc,0x9e,0x46,0x70,0x47,
0xf8,0xb5,0x00,0xbf,0xd5,0x01,0x00,0x20,0xf8,0xbc,0x08,0xbc,0x9e,0x46,0x70,0x47,
0x43,0x00,0x00,0x00,0x08,0x20,0x00,0x20,0x3c,0xf7,0xff,0x7f,0x01,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf4,0x22,0x00,0x20,
0x5c,0x23,0x00,0x20,0xc4,0x23,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0x0a,0x00,0x20,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0e,0x33,0xcd,0xab,0x34,0x12,0x6d,0xe6,
0xec,0xde,0x05,0x00,0x0b,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x08,0x20,0x00,0x20,

View File

@ -0,0 +1,102 @@
/******************************************************************************
*
* Copyright (C) 2012-2018 Texas Instruments Incorporated - http://www.ti.com/
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* distribution.
*
* Neither the name of Texas Instruments Incorporated nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************/
#ifndef OPENOCD_LOADERS_FLASH_MSP432_MSP432P401X_H
#define OPENOCD_LOADERS_FLASH_MSP432_MSP432P401X_H
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
#define __MCU_HAS_FLCTL__ /* Module FLCTL is available */
/* Device and peripheral memory map */
#define FLASH_BASE ((uint32_t)0x00000000) /* Flash memory start address */
#define SRAM_BASE ((uint32_t)0x20000000) /* SRAM memory start address */
#define PERIPH_BASE ((uint32_t)0x40000000) /* Peripherals start address */
#define CS_BASE (PERIPH_BASE + 0x00010400) /* Address of module CS regs. */
#define DIO_BASE (PERIPH_BASE + 0x00004C00) /* Address of module DIO regs. */
/* Register map for Clock Signal peripheral (CS) */
struct cs {
volatile uint32_t KEY; /* Key Register */
volatile uint32_t CTL0; /* Control 0 Register */
volatile uint32_t CTL1; /* Control 1 Register */
volatile uint32_t CTL2; /* Control 2 Register */
volatile uint32_t CTL3; /* Control 3 Register */
};
/* Register map for DIO port (odd interrupt) */
struct dio_port_odd_int {
volatile uint8_t IN; /* Port Input */
uint8_t RESERVED0;
volatile uint8_t OUT; /* Port Output */
};
/* Register map for DIO port (even interrupt) */
struct dio_port_even_int {
uint8_t RESERVED0;
volatile uint8_t IN; /* Port Input */
uint8_t RESERVED1;
volatile uint8_t OUT; /* Port Output */
};
/* Peripheral declarations */
#define CS ((struct cs *) CS_BASE)
#define P3 ((struct dio_port_odd_int *) (DIO_BASE + 0x0020))
#define P6 ((struct dio_port_even_int *) (DIO_BASE + 0x0040))
/* Peripheral bit definitions */
/* DCORSEL Bit Mask */
#define CS_CTL0_DCORSEL_MASK ((uint32_t)0x00070000)
/* Nominal DCO Frequency Range (MHz): 2 to 4 */
#define CS_CTL0_DCORSEL_1 ((uint32_t)0x00010000)
/* Nominal DCO Frequency Range (MHz): 16 to 32 */
#define CS_CTL0_DCORSEL_4 ((uint32_t)0x00040000)
/* CS control key value */
#define CS_KEY_VAL ((uint32_t)0x0000695A)
/* Protects Sector 0 from program or erase */
#define FLCTL_BANK0_MAIN_WEPROT_PROT0 ((uint32_t)0x00000001)
/* Protects Sector 1 from program or erase */
#define FLCTL_BANK0_MAIN_WEPROT_PROT1 ((uint32_t)0x00000002)
#ifdef __cplusplus
}
#endif
#endif /* OPENOCD_LOADERS_FLASH_MSP432_MSP432P401X_H */

View File

@ -0,0 +1,151 @@
/******************************************************************************
*
* Copyright (C) 2012-2018 Texas Instruments Incorporated - http://www.ti.com/
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* distribution.
*
* Neither the name of Texas Instruments Incorporated nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************/
MEMORY {
MAIN_FLASH (RX) : ORIGIN = 0x00000000, LENGTH = 0x00040000
INFO_FLASH (RX) : ORIGIN = 0x00200000, LENGTH = 0x00004000
SRAM_CODE_0(RWX): ORIGIN = 0x01000000, LENGTH = 0x00000110
SRAM_CODE_1(RWX): ORIGIN = 0x01000110, LENGTH = 0x00000030
SRAM_CODE_2(RWX): ORIGIN = 0x01000150, LENGTH = 0x00000040
SRAM_CODE_3(RWX): ORIGIN = 0x01000190, LENGTH = 0x00000F70
SRAM_CODE_4(RWX): ORIGIN = 0x01001170, LENGTH = 0x00000200
SRAM_DATA (RW) : ORIGIN = 0x20002000, LENGTH = 0x00001000
}
REGION_ALIAS("REGION_INTVECT", SRAM_CODE_0);
REGION_ALIAS("REGION_RESET", SRAM_CODE_1);
REGION_ALIAS("REGION_DESCRIPTOR", SRAM_CODE_2);
REGION_ALIAS("REGION_TEXT", SRAM_CODE_3);
REGION_ALIAS("REGION_BSS", SRAM_CODE_3);
REGION_ALIAS("REGION_DATA", SRAM_DATA);
REGION_ALIAS("REGION_STACK", SRAM_CODE_4);
REGION_ALIAS("REGION_HEAP", SRAM_DATA);
REGION_ALIAS("REGION_ARM_EXIDX", SRAM_CODE_3);
REGION_ALIAS("REGION_ARM_EXTAB", SRAM_CODE_3);
SECTIONS {
/* section for the interrupt vector area */
.intvecs : {
KEEP (*(.intvecs))
} > REGION_INTVECT
PROVIDE (_vtable_base_address =
DEFINED(_vtable_base_address) ? _vtable_base_address : 0x20000000);
.vtable (_vtable_base_address) : AT (_vtable_base_address) {
KEEP (*(.vtable))
} > REGION_DATA
.descriptor :{
FILL(0x00000000);
. = ORIGIN(REGION_DESCRIPTOR) + LENGTH(REGION_DESCRIPTOR) - 1;
BYTE(0x00);
__ROM_AT = .;
} > REGION_DESCRIPTOR
.reset : {
KEEP(*(.reset))
} > REGION_RESET AT> REGION_RESET
.text : {
CREATE_OBJECT_SYMBOLS
KEEP (*(.text))
*(.text.*)
. = ALIGN(0x4);
KEEP (*(.ctors))
. = ALIGN(0x4);
KEEP (*(.dtors))
. = ALIGN(0x4);
__init_array_start = .;
KEEP (*(.init_array*))
__init_array_end = .;
KEEP (*(.init))
KEEP (*(.fini*))
} > REGION_TEXT AT> REGION_TEXT
.rodata : {
*(.rodata)
*(.rodata.*)
} > REGION_TEXT AT> REGION_TEXT
.ARM.exidx : {
__exidx_start = .;
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
__exidx_end = .;
} > REGION_ARM_EXIDX AT> REGION_ARM_EXIDX
.ARM.extab : {
KEEP (*(.ARM.extab* .gnu.linkonce.armextab.*))
} > REGION_ARM_EXTAB AT> REGION_ARM_EXTAB
__etext = .;
.data : {
__data_load__ = LOADADDR (.data);
__data_start__ = .;
KEEP (*(.data))
KEEP (*(.data*))
. = ALIGN (4);
__data_end__ = .;
} > REGION_DATA AT> REGION_TEXT
.bss : {
__bss_start__ = .;
*(.shbss)
KEEP (*(.bss))
*(.bss.*)
*(COMMON)
. = ALIGN (4);
__bss_end__ = .;
} > REGION_BSS AT> REGION_BSS
.heap : {
__heap_start__ = .;
end = __heap_start__;
_end = end;
__end = end;
KEEP (*(.heap))
__heap_end__ = .;
__HeapLimit = __heap_end__;
} > REGION_HEAP AT> REGION_HEAP
.stack (NOLOAD) : ALIGN(0x8) {
_stack = .;
KEEP(*(.stack))
} > REGION_STACK AT> REGION_STACK
__stack_top = ORIGIN(REGION_STACK) + LENGTH(REGION_STACK);
PROVIDE(__stack = __stack_top);
}

View File

@ -0,0 +1,242 @@
/* Autogenerated with ../../../../src/helper/bin2char.sh */
0x70,0x13,0x00,0x01,0x11,0x01,0x00,0x01,0xa1,0x0a,0x00,0x01,0xa1,0x0a,0x00,0x01,
0xa1,0x0a,0x00,0x01,0xa1,0x0a,0x00,0x01,0xa1,0x0a,0x00,0x01,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa1,0x0a,0x00,0x01,
0xa1,0x0a,0x00,0x01,0x00,0x00,0x00,0x00,0xa1,0x0a,0x00,0x01,0xa1,0x0a,0x00,0x01,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x41,0xf2,0x00,0x70,0xc0,0xf2,0x00,0x10,0x85,0x46,0x05,0x48,0x05,0x49,0x4f,0xf0,
0x00,0x02,0x88,0x42,0xb8,0xbf,0x40,0xf8,0x04,0x2b,0xfa,0xdb,0x00,0xf0,0x96,0xbb,
0x0c,0x0f,0x00,0x01,0x28,0x0f,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x04,0x4b,0x05,0x48,0x1b,0x1a,0x06,0x2b,0x02,0xd9,0x04,0x4b,0x03,0xb1,0x18,0x47,
0x70,0x47,0x00,0xbf,0x37,0x24,0x00,0x20,0x34,0x24,0x00,0x20,0x00,0x00,0x00,0x00,
0x05,0x49,0x06,0x48,0x09,0x1a,0x89,0x10,0x01,0xeb,0xd1,0x71,0x49,0x10,0x02,0xd0,
0x03,0x4b,0x03,0xb1,0x18,0x47,0x70,0x47,0x34,0x24,0x00,0x20,0x34,0x24,0x00,0x20,
0x00,0x00,0x00,0x00,0x10,0xb5,0x06,0x4c,0x23,0x78,0x43,0xb9,0xff,0xf7,0xd8,0xff,
0x04,0x4b,0x13,0xb1,0x04,0x48,0xaf,0xf3,0x00,0x80,0x01,0x23,0x23,0x70,0x10,0xbd,
0x0c,0x0f,0x00,0x01,0x00,0x00,0x00,0x00,0xd0,0x0a,0x00,0x01,0x08,0xb5,0x08,0x4b,
0x1b,0xb1,0x08,0x48,0x08,0x49,0xaf,0xf3,0x00,0x80,0x08,0x48,0x03,0x68,0x13,0xb9,
0xbd,0xe8,0x08,0x40,0xcc,0xe7,0x06,0x4b,0x00,0x2b,0xf9,0xd0,0x98,0x47,0xf7,0xe7,
0x00,0x00,0x00,0x00,0xd0,0x0a,0x00,0x01,0x10,0x0f,0x00,0x01,0x34,0x24,0x00,0x20,
0x00,0x00,0x00,0x00,0x13,0x4b,0x00,0x2b,0x08,0xbf,0x11,0x4b,0x9d,0x46,0xa3,0xf5,
0x80,0x3a,0x00,0x21,0x8b,0x46,0x0f,0x46,0x11,0x48,0x12,0x4a,0x12,0x1a,0x00,0xf0,
0x79,0xf8,0x0d,0x4b,0x00,0x2b,0x00,0xd0,0x98,0x47,0x0c,0x4b,0x00,0x2b,0x00,0xd0,
0x98,0x47,0x00,0x20,0x00,0x21,0x04,0x00,0x0d,0x00,0x0b,0x48,0x00,0xf0,0x16,0xf8,
0x00,0xf0,0x40,0xf8,0x20,0x00,0x29,0x00,0x00,0xf0,0xf0,0xfa,0x00,0xf0,0x14,0xf8,
0x00,0x00,0x08,0x00,0x70,0x13,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x0c,0x0f,0x00,0x01,0x28,0x0f,0x00,0x01,0xc9,0x02,0x00,0x01,0x01,0x46,0x00,0x20,
0x02,0x46,0x03,0x46,0x00,0xf0,0x9c,0xb8,0x08,0xb5,0x00,0x21,0x04,0x46,0x00,0xf0,
0xf3,0xf8,0x04,0x4b,0x18,0x68,0xc3,0x6b,0x03,0xb1,0x98,0x47,0x20,0x46,0x00,0xf0,
0x55,0xf9,0x00,0xbf,0xcc,0x0a,0x00,0x01,0x38,0xb5,0x08,0x4b,0x08,0x4d,0xed,0x1a,
0xac,0x10,0x18,0xbf,0xed,0x18,0x05,0xd0,0x01,0x3c,0x55,0xf8,0x04,0x3d,0x98,0x47,
0x00,0x2c,0xf9,0xd1,0xbd,0xe8,0x38,0x40,0x00,0xf0,0xe6,0xbb,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x70,0xb5,0x0f,0x4e,0x0f,0x4d,0x76,0x1b,0xb6,0x10,0x18,0xbf,
0x00,0x24,0x05,0xd0,0x01,0x34,0x55,0xf8,0x04,0x3b,0x98,0x47,0xa6,0x42,0xf9,0xd1,
0x0a,0x4e,0x0b,0x4d,0x76,0x1b,0x00,0xf0,0xc9,0xfb,0xb6,0x10,0x18,0xbf,0x00,0x24,
0x06,0xd0,0x01,0x34,0x55,0xf8,0x04,0x3b,0x98,0x47,0xa6,0x42,0xf9,0xd1,0x70,0xbd,
0x70,0xbd,0x00,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xac,0x0a,0x00,0x01,
0xa4,0x0a,0x00,0x01,0x70,0xb4,0x84,0x07,0x46,0xd0,0x54,0x1e,0x00,0x2a,0x41,0xd0,
0xcd,0xb2,0x03,0x46,0x02,0xe0,0x62,0x1e,0xe4,0xb3,0x14,0x46,0x03,0xf8,0x01,0x5b,
0x9a,0x07,0xf8,0xd1,0x03,0x2c,0x2e,0xd9,0xcd,0xb2,0x45,0xea,0x05,0x25,0x0f,0x2c,
0x45,0xea,0x05,0x45,0x19,0xd9,0x03,0xf1,0x10,0x02,0x26,0x46,0x10,0x3e,0x0f,0x2e,
0x42,0xf8,0x10,0x5c,0x42,0xf8,0x0c,0x5c,0x42,0xf8,0x08,0x5c,0x42,0xf8,0x04,0x5c,
0x02,0xf1,0x10,0x02,0xf2,0xd8,0xa4,0xf1,0x10,0x02,0x22,0xf0,0x0f,0x02,0x04,0xf0,
0x0f,0x04,0x10,0x32,0x03,0x2c,0x13,0x44,0x0d,0xd9,0x1e,0x46,0x22,0x46,0x04,0x3a,
0x03,0x2a,0x46,0xf8,0x04,0x5b,0xfa,0xd8,0x22,0x1f,0x22,0xf0,0x03,0x02,0x04,0x32,
0x13,0x44,0x04,0xf0,0x03,0x04,0x2c,0xb1,0xc9,0xb2,0x1c,0x44,0x03,0xf8,0x01,0x1b,
0xa3,0x42,0xfb,0xd1,0x70,0xbc,0x70,0x47,0x14,0x46,0x03,0x46,0xc2,0xe7,0x00,0xbf,
0x2d,0xe9,0xf0,0x47,0x25,0x4c,0x25,0x68,0xd5,0xf8,0x48,0x41,0x06,0x46,0x88,0x46,
0x92,0x46,0x99,0x46,0xcc,0xb3,0x60,0x68,0x1f,0x28,0x18,0xdc,0x43,0x1c,0x7e,0xb1,
0x04,0xeb,0x80,0x05,0x01,0x21,0xc5,0xf8,0x88,0xa0,0xd4,0xf8,0x88,0x71,0x01,0xfa,
0x00,0xf2,0x17,0x43,0x02,0x2e,0xc4,0xf8,0x88,0x71,0xc5,0xf8,0x08,0x91,0x1e,0xd0,
0x02,0x30,0x63,0x60,0x44,0xf8,0x20,0x80,0x00,0x20,0xbd,0xe8,0xf0,0x87,0x14,0x4b,
0x03,0xb3,0x4f,0xf4,0xc8,0x70,0xaf,0xf3,0x00,0x80,0x04,0x46,0xd0,0xb1,0xd5,0xf8,
0x48,0x31,0x00,0x27,0x80,0xe8,0x88,0x00,0xc5,0xf8,0x48,0x41,0x38,0x46,0x01,0x23,
0xc4,0xf8,0x88,0x71,0xc4,0xf8,0x8c,0x71,0x00,0x2e,0xe1,0xd0,0xd0,0xe7,0xd4,0xf8,
0x8c,0x11,0x0a,0x43,0xc4,0xf8,0x8c,0x21,0xda,0xe7,0x05,0xf5,0xa6,0x74,0xc5,0xf8,
0x48,0x41,0xc0,0xe7,0x4f,0xf0,0xff,0x30,0xbd,0xe8,0xf0,0x87,0xcc,0x0a,0x00,0x01,
0x00,0x00,0x00,0x00,0x02,0x4b,0x13,0xb1,0x02,0x48,0xff,0xf7,0x07,0xbf,0x70,0x47,
0x00,0x00,0x00,0x00,0xc9,0x02,0x00,0x01,0x2d,0xe9,0xf0,0x4f,0x31,0x4b,0x83,0xb0,
0x1b,0x68,0x00,0x93,0x03,0xf5,0xa4,0x73,0x81,0x46,0x0e,0x46,0x01,0x93,0x00,0x9b,
0xd3,0xf8,0x48,0x71,0x27,0xb3,0xdd,0xf8,0x04,0xa0,0x7c,0x68,0x65,0x1e,0x0e,0xd4,
0x01,0x34,0x07,0xeb,0x84,0x04,0x4f,0xf0,0x00,0x08,0xe6,0xb1,0xd4,0xf8,0x00,0x31,
0xb3,0x42,0x18,0xd0,0x01,0x3d,0x6b,0x1c,0xa4,0xf1,0x04,0x04,0xf5,0xd1,0x22,0x4b,
0x73,0xb1,0x7b,0x68,0x00,0x2b,0x36,0xd1,0x3b,0x68,0x00,0x2b,0x34,0xd0,0x38,0x46,
0xca,0xf8,0x00,0x30,0xaf,0xf3,0x00,0x80,0xda,0xf8,0x00,0x70,0x00,0x2f,0xdc,0xd1,
0x03,0xb0,0xbd,0xe8,0xf0,0x8f,0x7b,0x68,0x22,0x68,0x01,0x3b,0xab,0x42,0x0c,0xbf,
0x7d,0x60,0xc4,0xf8,0x00,0x80,0x00,0x2a,0xdc,0xd0,0xd7,0xf8,0x88,0x31,0xd7,0xf8,
0x04,0xb0,0x01,0x21,0xa9,0x40,0x19,0x42,0x08,0xd1,0x90,0x47,0x7b,0x68,0x5b,0x45,
0xbd,0xd1,0xda,0xf8,0x00,0x30,0xbb,0x42,0xcc,0xd0,0xb8,0xe7,0xd7,0xf8,0x8c,0x31,
0x19,0x42,0x04,0xd1,0x48,0x46,0xd4,0xf8,0x80,0x10,0x90,0x47,0xee,0xe7,0xd4,0xf8,
0x80,0x00,0x90,0x47,0xea,0xe7,0x3b,0x68,0xba,0x46,0x1f,0x46,0x00,0x2f,0xac,0xd1,
0xce,0xe7,0x00,0xbf,0xcc,0x0a,0x00,0x01,0x00,0x00,0x00,0x00,0xfe,0xe7,0x00,0xbf,
0xef,0xf3,0x10,0x80,0x72,0xb6,0x70,0x47,0xf8,0xb5,0x20,0x4e,0x20,0x4a,0x33,0x68,
0x20,0x4d,0x21,0x4f,0x21,0x4c,0x4f,0xf0,0x80,0x71,0x91,0x60,0x9b,0x6d,0x00,0x20,
0x98,0x47,0x33,0x68,0x28,0x60,0x9b,0x6d,0x01,0x20,0x98,0x47,0x3b,0x68,0x68,0x60,
0x5b,0x68,0x98,0x47,0x3b,0x68,0x28,0x73,0x1b,0x6a,0x98,0x47,0x63,0x68,0x3a,0x68,
0x68,0x73,0x03,0xf4,0xe0,0x23,0xab,0x60,0x93,0x69,0x00,0x20,0x98,0x47,0x33,0x68,
0x02,0x21,0x5b,0x6d,0x05,0x46,0x00,0x20,0x98,0x47,0x33,0x68,0x01,0x20,0x5b,0x6d,
0x02,0x21,0x98,0x47,0x46,0xf6,0x5a,0x13,0x23,0x60,0x63,0x68,0x23,0xf4,0xe0,0x23,
0x43,0xf4,0x80,0x23,0x00,0x22,0x63,0x60,0x22,0x60,0x09,0x4b,0x1d,0xb1,0x40,0xf6,
0xce,0x22,0x5a,0x60,0xf8,0xbd,0x07,0x4a,0x5a,0x60,0xf8,0xbd,0x1c,0x08,0x00,0x02,
0x00,0xed,0x00,0xe0,0x80,0x01,0x00,0x20,0x34,0x08,0x00,0x02,0x00,0x04,0x01,0x40,
0x50,0x01,0x00,0x20,0x00,0xad,0xde,0x00,0x2d,0xe9,0xf8,0x4f,0x4e,0x4c,0x25,0x69,
0xe7,0x68,0x00,0x2d,0x6d,0xd0,0xdf,0xf8,0x38,0xb1,0xdf,0xf8,0x38,0xa1,0xdf,0xf8,
0x38,0x91,0x4f,0xf0,0x00,0x08,0xdb,0xf8,0x00,0x30,0xb5,0xf5,0x80,0x5f,0x1b,0x69,
0x4f,0xf0,0xff,0x31,0x4f,0xf0,0x01,0x00,0x93,0xbf,0x2e,0x46,0xa5,0xf5,0x80,0x55,
0x4f,0xf4,0x80,0x56,0x00,0x25,0x98,0x47,0xdb,0xf8,0x00,0x30,0x4f,0xf0,0xff,0x31,
0x1b,0x69,0x02,0x20,0x98,0x47,0xdb,0xf8,0x00,0x30,0x03,0x20,0x1b,0x69,0x01,0x46,
0x98,0x47,0x23,0x6a,0x0b,0x2b,0x03,0xd1,0x60,0xe0,0xa3,0x69,0xd9,0x06,0x02,0xd4,
0x63,0x69,0xd8,0x06,0xf9,0xd5,0x63,0x69,0xda,0x06,0x3c,0xd5,0x63,0x69,0xdb,0xf8,
0x00,0x20,0x43,0xf0,0x01,0x03,0x63,0x61,0x93,0x6a,0x39,0x46,0x4f,0xf0,0x20,0x20,
0x32,0x46,0x98,0x47,0x99,0xf8,0x03,0x30,0x03,0xf0,0xef,0x03,0x89,0xf8,0x03,0x30,
0x63,0x69,0x23,0xf0,0x11,0x03,0x80,0x46,0x37,0x44,0x63,0x61,0xdb,0xf8,0x00,0x30,
0x4f,0xf0,0xff,0x31,0x5b,0x69,0x01,0x20,0x98,0x47,0xdb,0xf8,0x00,0x30,0x4f,0xf0,
0xff,0x31,0x5b,0x69,0x02,0x20,0x98,0x47,0xdb,0xf8,0x00,0x30,0x03,0x20,0x5b,0x69,
0x01,0x46,0x98,0x47,0xdb,0xf8,0x00,0x30,0x04,0x20,0x5b,0x69,0x03,0x21,0x98,0x47,
0xb8,0xf1,0x00,0x0f,0x29,0xd0,0x00,0x2d,0x9d,0xd1,0x17,0x4b,0x40,0xf6,0xce,0x22,
0x5a,0x60,0xbd,0xe8,0xf8,0x8f,0xa3,0x69,0xdb,0x06,0xd7,0xd5,0xa3,0x69,0xdb,0xf8,
0x00,0x20,0x12,0x48,0x43,0xf0,0x01,0x03,0xa3,0x61,0x93,0x6a,0x39,0x46,0x32,0x46,
0x98,0x47,0x9a,0xf8,0x02,0x30,0x03,0xf0,0xbf,0x03,0x8a,0xf8,0x02,0x30,0xa3,0x69,
0x23,0xf0,0x11,0x03,0x80,0x46,0x37,0x44,0xa3,0x61,0xbf,0xe7,0xdb,0xf8,0x00,0x30,
0x03,0x21,0x1b,0x69,0x04,0x20,0x98,0x47,0x9a,0xe7,0x03,0x4b,0x4d,0xf6,0xad,0x62,
0x5a,0x60,0xbd,0xe8,0xf8,0x8f,0x00,0xbf,0x50,0x01,0x00,0x20,0x00,0x30,0x00,0x20,
0x1c,0x08,0x00,0x02,0x20,0x4c,0x00,0x40,0x40,0x4c,0x00,0x40,0x13,0x4b,0xdb,0x69,
0xda,0x07,0x70,0xb5,0x14,0xd4,0x11,0x4c,0xe3,0x69,0x9b,0x07,0x00,0xd4,0x70,0xbd,
0x0f,0x4d,0x2b,0x68,0x03,0x20,0x1b,0x69,0x01,0x46,0x98,0x47,0x23,0x6a,0x0b,0x2b,
0xf5,0xd1,0x2b,0x68,0x04,0x20,0x1b,0x69,0x03,0x21,0xbd,0xe8,0x70,0x40,0x18,0x47,
0x07,0x4c,0x23,0x68,0x4f,0xf0,0xff,0x31,0x1b,0x69,0x01,0x20,0x98,0x47,0x23,0x68,
0x4f,0xf0,0xff,0x31,0x1b,0x69,0x02,0x20,0x98,0x47,0xdc,0xe7,0x50,0x01,0x00,0x20,
0x1c,0x08,0x00,0x02,0x2d,0xe9,0xf8,0x43,0x1e,0x4c,0x1f,0x4d,0x1f,0x4f,0x29,0x68,
0x3a,0x68,0xdf,0xf8,0x84,0x90,0x46,0xf6,0x5a,0x18,0xc4,0xf8,0x00,0x80,0x63,0x68,
0x23,0xf4,0xe0,0x23,0x00,0x26,0x43,0xf4,0x80,0x33,0x63,0x60,0x26,0x60,0x53,0x6d,
0x30,0x46,0x98,0x47,0x3b,0x68,0x69,0x68,0x5b,0x6d,0x01,0x20,0x98,0x47,0xd9,0xf8,
0x00,0x30,0x68,0x7b,0x9b,0x69,0x98,0x47,0xd9,0xf8,0x00,0x30,0x07,0x46,0x1b,0x68,
0x28,0x7b,0x98,0x47,0xc4,0xf8,0x00,0x80,0x63,0x68,0xaa,0x68,0x0c,0x49,0x23,0xf4,
0xe0,0x23,0x13,0x43,0x63,0x60,0x26,0x60,0x0a,0x4b,0x8e,0x60,0x28,0xb1,0x27,0xb1,
0x40,0xf6,0xce,0x22,0x5a,0x60,0xbd,0xe8,0xf8,0x83,0x4d,0xf6,0xad,0x62,0x5a,0x60,
0xbd,0xe8,0xf8,0x83,0x00,0x04,0x01,0x40,0x80,0x01,0x00,0x20,0x1c,0x08,0x00,0x02,
0x00,0xed,0x00,0xe0,0x50,0x01,0x00,0x20,0x34,0x08,0x00,0x02,0x8c,0x4b,0x8d,0x4c,
0x1b,0x68,0x8d,0x4d,0x1b,0x68,0x80,0xb5,0x98,0x47,0xff,0xf7,0x81,0xfe,0x27,0x46,
0x23,0x68,0x20,0x2b,0x00,0xf2,0xeb,0x80,0x01,0xa2,0x52,0xf8,0x23,0xf0,0x00,0xbf,
0x71,0x08,0x00,0x01,0xff,0x09,0x00,0x01,0xb9,0x09,0x00,0x01,0x4f,0x0a,0x00,0x01,
0x2f,0x09,0x00,0x01,0x4f,0x0a,0x00,0x01,0x4f,0x0a,0x00,0x01,0x4f,0x0a,0x00,0x01,
0x21,0x09,0x00,0x01,0x4f,0x0a,0x00,0x01,0x4f,0x0a,0x00,0x01,0x4f,0x0a,0x00,0x01,
0x4f,0x0a,0x00,0x01,0x4f,0x0a,0x00,0x01,0x4f,0x0a,0x00,0x01,0x4f,0x0a,0x00,0x01,
0x13,0x09,0x00,0x01,0x4f,0x0a,0x00,0x01,0x4f,0x0a,0x00,0x01,0x4f,0x0a,0x00,0x01,
0x4f,0x0a,0x00,0x01,0x4f,0x0a,0x00,0x01,0x4f,0x0a,0x00,0x01,0x4f,0x0a,0x00,0x01,
0x4f,0x0a,0x00,0x01,0x4f,0x0a,0x00,0x01,0x4f,0x0a,0x00,0x01,0x4f,0x0a,0x00,0x01,
0x4f,0x0a,0x00,0x01,0x4f,0x0a,0x00,0x01,0x4f,0x0a,0x00,0x01,0x4f,0x0a,0x00,0x01,
0x05,0x09,0x00,0x01,0x01,0x23,0x63,0x60,0xff,0xf7,0x86,0xfe,0x00,0x23,0x23,0x60,
0xae,0xe7,0x01,0x23,0x63,0x60,0xff,0xf7,0x55,0xff,0x00,0x23,0x23,0x60,0xa7,0xe7,
0x01,0x23,0x63,0x60,0xff,0xf7,0x28,0xfe,0x00,0x23,0x23,0x60,0xa0,0xe7,0x2b,0x68,
0x01,0x20,0x60,0x60,0x1b,0x69,0x4f,0xf0,0xff,0x31,0x98,0x47,0x2b,0x68,0x4f,0xf0,
0xff,0x31,0x1b,0x69,0x02,0x20,0x98,0x47,0x2b,0x68,0x03,0x20,0x1b,0x69,0x01,0x46,
0x98,0x47,0x23,0x6a,0x0b,0x2b,0x00,0xf0,0x82,0x80,0x63,0x69,0xdb,0x06,0xfc,0xd5,
0x7b,0x69,0x28,0x68,0x43,0xf0,0x01,0x03,0x7b,0x61,0xf9,0x68,0x83,0x6a,0x3a,0x69,
0x4f,0xf0,0x20,0x20,0x98,0x47,0x7b,0x69,0x2a,0x68,0x23,0xf0,0x11,0x03,0x7b,0x61,
0x53,0x69,0x06,0x46,0x4f,0xf0,0xff,0x31,0x01,0x20,0x98,0x47,0x2b,0x68,0x4f,0xf0,
0xff,0x31,0x5b,0x69,0x02,0x20,0x98,0x47,0x2b,0x68,0x03,0x20,0x5b,0x69,0x01,0x46,
0x98,0x47,0x2b,0x68,0x04,0x20,0x5b,0x69,0x03,0x21,0x98,0x47,0x00,0x2e,0x52,0xd0,
0x40,0xf6,0xce,0x23,0x7b,0x60,0xb0,0xe7,0x2b,0x68,0x01,0x20,0x60,0x60,0x1b,0x69,
0x4f,0xf0,0xff,0x31,0x98,0x47,0x2b,0x68,0x4f,0xf0,0xff,0x31,0x1b,0x69,0x02,0x20,
0x98,0x47,0x2b,0x68,0x03,0x20,0x1b,0x69,0x01,0x46,0x98,0x47,0x23,0x6a,0x0b,0x2b,
0x43,0xd0,0x05,0x26,0x2b,0x68,0xe0,0x68,0x5b,0x6a,0x98,0x47,0x01,0x3e,0x00,0x28,
0x47,0xd1,0x00,0x2e,0xf6,0xd1,0x4d,0xf6,0xad,0x63,0x63,0x60,0x0e,0xe0,0x01,0x23,
0x63,0x60,0xff,0xf7,0xb3,0xfe,0x05,0x26,0x2b,0x68,0x1b,0x6a,0x98,0x47,0x01,0x3e,
0x00,0x28,0x30,0xd1,0x00,0x2e,0xf7,0xd1,0x20,0x4b,0x63,0x60,0x2b,0x68,0x4f,0xf0,
0xff,0x31,0x5b,0x69,0x01,0x20,0x98,0x47,0x2b,0x68,0x4f,0xf0,0xff,0x31,0x5b,0x69,
0x02,0x20,0x98,0x47,0x2b,0x68,0x03,0x20,0x5b,0x69,0x01,0x46,0x98,0x47,0x2b,0x68,
0x04,0x20,0x5b,0x69,0x03,0x21,0x98,0x47,0x00,0x23,0x23,0x60,0x10,0xe7,0x40,0xf6,
0xad,0x33,0x63,0x60,0x0c,0xe7,0x4d,0xf6,0xad,0x63,0x7b,0x60,0x5d,0xe7,0x2b,0x68,
0x03,0x21,0x1b,0x69,0x04,0x20,0x98,0x47,0x77,0xe7,0x2b,0x68,0x03,0x21,0x1b,0x69,
0x04,0x20,0x98,0x47,0xb5,0xe7,0x00,0x2e,0xce,0xd0,0x40,0xf6,0xce,0x23,0x63,0x60,
0xcc,0xe7,0x00,0x2e,0xb7,0xd0,0x40,0xf6,0xce,0x23,0x7b,0x60,0xc6,0xe7,0x00,0xbf,
0x64,0x08,0x00,0x02,0x50,0x01,0x00,0x20,0x1c,0x08,0x00,0x02,0xad,0xde,0xad,0xde,
0xfe,0xe7,0x00,0xbf,0xfd,0x01,0x00,0x01,0x85,0x04,0x00,0x01,0xf8,0xb5,0x00,0xbf,
0xf8,0xbc,0x08,0xbc,0x9e,0x46,0x70,0x47,0xf8,0xb5,0x00,0xbf,0xd5,0x01,0x00,0x01,
0xf8,0xbc,0x08,0xbc,0x9e,0x46,0x70,0x47,0x43,0x00,0x00,0x00,0x08,0x20,0x00,0x20,
0x64,0xf7,0xff,0x7f,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0xf4,0x22,0x00,0x20,0x5c,0x23,0x00,0x20,0xc4,0x23,0x00,0x20,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0xc8,0x0a,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x0e,0x33,0xcd,0xab,0x34,0x12,0x6d,0xe6,0xec,0xde,0x05,0x00,0x0b,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x20,0x00,0x20,

View File

@ -0,0 +1,164 @@
/******************************************************************************
*
* Copyright (C) 2012-2018 Texas Instruments Incorporated - http://www.ti.com/
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* distribution.
*
* Neither the name of Texas Instruments Incorporated nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************/
#ifndef OPENOCD_LOADERS_FLASH_MSP432_MSP432P411X_H
#define OPENOCD_LOADERS_FLASH_MSP432_MSP432P411X_H
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/* Available Peripherals */
#define __MCU_HAS_FLCTL_A__ /* Module FLCTL_A is available */
#define __MCU_HAS_SYSCTL_A__ /* Module SYSCTL_A is available */
/* Device and Peripheral Memory Map */
#define FLASH_BASE ((uint32_t)0x00000000) /* Flash memory address */
#define PERIPH_BASE ((uint32_t)0x40000000) /* Peripherals address */
#define CS_BASE (PERIPH_BASE + 0x00010400) /* Address of CS regs. */
#define PCM_BASE (PERIPH_BASE + 0x00010000) /* Address of PCM regs. */
#define RTC_C_BASE (PERIPH_BASE + 0x00004400) /* Address of RTC_C regs */
#define TLV_BASE ((uint32_t)0x00201000) /* Address of TLV regs. */
#define WDT_A_BASE (PERIPH_BASE + 0x00004800) /* Address of WDT_A regs */
#define BITBAND_PERI_BASE ((uint32_t)(0x42000000))
/*
* Peripherals with 8-bit or 16-bit register access allow only 8-bit or
* 16-bit bit band access, so cast to 8 bit always
*/
#define BITBAND_PERI(x, b) (*((volatile uint8_t *) (BITBAND_PERI_BASE + \
(((uint32_t)(uint32_t *)&(x)) - PERIPH_BASE)*32 + (b)*4)))
/* Register map for CLock Signal peripheral (CS) */
struct cs {
volatile uint32_t KEY; /* Key Register */
volatile uint32_t CTL0; /* Control 0 Register */
volatile uint32_t CTL1; /* Control 1 Register */
volatile uint32_t CTL2; /* Control 2 Register */
volatile uint32_t CTL3; /* Control 3 Register */
};
/* Register map for Power Control Module peripheral (PCM) */
struct pcm {
volatile uint32_t CTL0; /* Control 0 Register */
volatile uint32_t CTL1; /* Control 1 Register */
volatile uint32_t IE; /* Interrupt Enable Register */
volatile uint32_t IFG; /* Interrupt Flag Register */
volatile uint32_t CLRIFG; /* Clear Interrupt Flag Register */
};
/* Register map for Real-Time Clock peripheral (RTC_C) */
struct rtc_c {
volatile uint16_t CTL0; /* RTCCTL0 Register */
volatile uint16_t CTL13; /* RTCCTL13 Register */
volatile uint16_t OCAL; /* RTCOCAL Register */
volatile uint16_t TCMP; /* RTCTCMP Register */
volatile uint16_t PS0CTL; /* RTC Prescale Timer 0 Control Register */
volatile uint16_t PS1CTL; /* RTC Prescale Timer 1 Control Register */
volatile uint16_t PS; /* Real-Time Clock Prescale Timer Register */
volatile uint16_t IV; /* Real-Time Clock Interrupt Vector Register */
volatile uint16_t TIM0; /* RTCTIM0 Register Hexadecimal Format */
volatile uint16_t TIM1; /* Real-Time Clock Hour, Day of Week */
volatile uint16_t DATE; /* RTCDATE - Hexadecimal Format */
volatile uint16_t YEAR; /* RTCYEAR Register - Hexadecimal Format */
volatile uint16_t AMINHR; /* RTCMINHR - Hexadecimal Format */
volatile uint16_t ADOWDAY; /* RTCADOWDAY - Hexadecimal Format */
volatile uint16_t BIN2BCD; /* Binary-to-BCD Conversion Register */
volatile uint16_t BCD2BIN; /* BCD-to-Binary Conversion Register */
};
/* Register map for Watchdog Timer peripheral (WDT_A) */
struct wdt_a {
uint16_t RESERVED0[6];
volatile uint16_t CTL; /* Watchdog Timer Control Register */
};
/* Peripheral Declarations */
#define CS ((struct cs *) CS_BASE)
#define PCM ((struct pcm *) PCM_BASE)
#define RTC_C ((struct rtc_c *) RTC_C_BASE)
#define WDT_A ((struct wdt_a *) WDT_A_BASE)
/* Peripheral Register Bit Definitions */
/* DCORSEL Bit Mask */
#define CS_CTL0_DCORSEL_MASK ((uint32_t)0x00070000)
/* Nominal DCO Frequency Range (MHz): 2 to 4 */
#define CS_CTL0_DCORSEL_1 ((uint32_t)0x00010000)
/* Nominal DCO Frequency Range (MHz): 16 to 32 */
#define CS_CTL0_DCORSEL_4 ((uint32_t)0x00040000)
/* CS control key value */
#define CS_KEY_VAL ((uint32_t)0x0000695A)
/* AMR Bit Mask */
#define PCM_CTL0_AMR_MASK ((uint32_t)0x0000000F)
/* LPMR Bit Mask */
#define PCM_CTL0_LPMR_MASK ((uint32_t)0x000000F0)
/* LPM3.5. Core voltage setting 0. */
#define PCM_CTL0_LPMR_10 ((uint32_t)0x000000A0)
/* LPM4.5 */
#define PCM_CTL0_LPMR_12 ((uint32_t)0x000000C0)
/* CPM Bit Offset */
#define PCM_CTL0_CPM_OFS (8)
/* CPM Bit Mask */
#define PCM_CTL0_CPM_MASK ((uint32_t)0x00003F00)
/* PCMKEY Bit Mask */
#define PCM_CTL0_KEY_MASK ((uint32_t)0xFFFF0000)
/* PMR_BUSY Bit Offset */
#define PCM_CTL1_PMR_BUSY_OFS (8)
/* RTCKEY Bit Offset */
#define RTC_C_CTL0_KEY_OFS (8)
/* RTCKEY Bit Mask */
#define RTC_C_CTL0_KEY_MASK ((uint16_t)0xFF00)
/* RTCHOLD Bit Offset */
#define RTC_C_CTL13_HOLD_OFS (6)
/* RTC_C Key Value for RTC_C write access */
#define RTC_C_KEY ((uint16_t)0xA500)
/* Watchdog timer hold */
#define WDT_A_CTL_HOLD ((uint16_t)0x0080)
/* WDT Key Value for WDT write access */
#define WDT_A_CTL_PW ((uint16_t)0x5A00)
/* Address of BSL API table */
#define BSL_API_TABLE_ADDR ((uint32_t)0x00202000)
#ifdef __cplusplus
}
#endif
#endif /* OPENOCD_LOADERS_FLASH_MSP432_MSP432P411X_H */

View File

@ -0,0 +1,151 @@
/******************************************************************************
*
* Copyright (C) 2012-2018 Texas Instruments Incorporated - http://www.ti.com/
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* distribution.
*
* Neither the name of Texas Instruments Incorporated nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************/
MEMORY {
MAIN_FLASH (RX) : ORIGIN = 0x00000000, LENGTH = 0x00200000
INFO_FLASH (RX) : ORIGIN = 0x00200000, LENGTH = 0x00008000
SRAM_CODE_0(RWX): ORIGIN = 0x01000000, LENGTH = 0x00000110
SRAM_CODE_1(RWX): ORIGIN = 0x01000110, LENGTH = 0x00000030
SRAM_CODE_2(RWX): ORIGIN = 0x01000150, LENGTH = 0x00000040
SRAM_CODE_3(RWX): ORIGIN = 0x01000190, LENGTH = 0x00001E70
SRAM_CODE_4(RWX): ORIGIN = 0x01002000, LENGTH = 0x00000200
SRAM_DATA (RW) : ORIGIN = 0x20002000, LENGTH = 0x00001000
}
REGION_ALIAS("REGION_INTVECT", SRAM_CODE_0);
REGION_ALIAS("REGION_RESET", SRAM_CODE_1);
REGION_ALIAS("REGION_DESCRIPTOR", SRAM_CODE_2);
REGION_ALIAS("REGION_TEXT", SRAM_CODE_3);
REGION_ALIAS("REGION_BSS", SRAM_CODE_3);
REGION_ALIAS("REGION_DATA", SRAM_DATA);
REGION_ALIAS("REGION_STACK", SRAM_CODE_4);
REGION_ALIAS("REGION_HEAP", SRAM_DATA);
REGION_ALIAS("REGION_ARM_EXIDX", SRAM_CODE_3);
REGION_ALIAS("REGION_ARM_EXTAB", SRAM_CODE_3);
SECTIONS {
/* section for the interrupt vector area */
.intvecs : {
KEEP (*(.intvecs))
} > REGION_INTVECT
PROVIDE (_vtable_base_address =
DEFINED(_vtable_base_address) ? _vtable_base_address : 0x20000000);
.vtable (_vtable_base_address) : AT (_vtable_base_address) {
KEEP (*(.vtable))
} > REGION_DATA
.descriptor :{
FILL(0x00000000);
. = ORIGIN(REGION_DESCRIPTOR) + LENGTH(REGION_DESCRIPTOR) - 1;
BYTE(0x00);
__ROM_AT = .;
} > REGION_DESCRIPTOR
.reset : {
KEEP(*(.reset))
} > REGION_RESET AT> REGION_RESET
.text : {
CREATE_OBJECT_SYMBOLS
KEEP (*(.text))
*(.text.*)
. = ALIGN(0x4);
KEEP (*(.ctors))
. = ALIGN(0x4);
KEEP (*(.dtors))
. = ALIGN(0x4);
__init_array_start = .;
KEEP (*(.init_array*))
__init_array_end = .;
KEEP (*(.init))
KEEP (*(.fini*))
} > REGION_TEXT AT> REGION_TEXT
.rodata : {
*(.rodata)
*(.rodata.*)
} > REGION_TEXT AT> REGION_TEXT
.ARM.exidx : {
__exidx_start = .;
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
__exidx_end = .;
} > REGION_ARM_EXIDX AT> REGION_ARM_EXIDX
.ARM.extab : {
KEEP (*(.ARM.extab* .gnu.linkonce.armextab.*))
} > REGION_ARM_EXTAB AT> REGION_ARM_EXTAB
__etext = .;
.data : {
__data_load__ = LOADADDR (.data);
__data_start__ = .;
KEEP (*(.data))
KEEP (*(.data*))
. = ALIGN (4);
__data_end__ = .;
} > REGION_DATA AT> REGION_TEXT
.bss : {
__bss_start__ = .;
*(.shbss)
KEEP (*(.bss))
*(.bss.*)
*(COMMON)
. = ALIGN (4);
__bss_end__ = .;
} > REGION_BSS AT> REGION_BSS
.heap : {
__heap_start__ = .;
end = __heap_start__;
_end = end;
__end = end;
KEEP (*(.heap))
__heap_end__ = .;
__HeapLimit = __heap_end__;
} > REGION_HEAP AT> REGION_HEAP
.stack (NOLOAD) : ALIGN(0x8) {
_stack = .;
KEEP(*(.stack))
} > REGION_STACK AT> REGION_STACK
__stack_top = ORIGIN(REGION_STACK) + LENGTH(REGION_STACK);
PROVIDE(__stack = __stack_top);
}

View File

@ -0,0 +1,361 @@
/* Autogenerated with ../../../../src/helper/bin2char.sh */
0x00,0x22,0x00,0x01,0x11,0x01,0x00,0x01,0x0d,0x12,0x00,0x01,0x0d,0x12,0x00,0x01,
0x0d,0x12,0x00,0x01,0x0d,0x12,0x00,0x01,0x0d,0x12,0x00,0x01,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0d,0x12,0x00,0x01,
0x0d,0x12,0x00,0x01,0x00,0x00,0x00,0x00,0x0d,0x12,0x00,0x01,0x0d,0x12,0x00,0x01,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x41,0xf2,0x00,0x70,0xc0,0xf2,0x00,0x10,0x85,0x46,0x05,0x48,0x05,0x49,0x4f,0xf0,
0x00,0x02,0x88,0x42,0xb8,0xbf,0x40,0xf8,0x04,0x2b,0xfa,0xdb,0x00,0xf0,0xaa,0xbf,
0x78,0x16,0x00,0x01,0x94,0x16,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x04,0x4b,0x05,0x48,0x1b,0x1a,0x06,0x2b,0x02,0xd9,0x04,0x4b,0x03,0xb1,0x18,0x47,
0x70,0x47,0x00,0xbf,0x37,0x24,0x00,0x20,0x34,0x24,0x00,0x20,0x00,0x00,0x00,0x00,
0x05,0x49,0x06,0x48,0x09,0x1a,0x89,0x10,0x01,0xeb,0xd1,0x71,0x49,0x10,0x02,0xd0,
0x03,0x4b,0x03,0xb1,0x18,0x47,0x70,0x47,0x34,0x24,0x00,0x20,0x34,0x24,0x00,0x20,
0x00,0x00,0x00,0x00,0x10,0xb5,0x06,0x4c,0x23,0x78,0x43,0xb9,0xff,0xf7,0xd8,0xff,
0x04,0x4b,0x13,0xb1,0x04,0x48,0xaf,0xf3,0x00,0x80,0x01,0x23,0x23,0x70,0x10,0xbd,
0x78,0x16,0x00,0x01,0x00,0x00,0x00,0x00,0x3c,0x12,0x00,0x01,0x08,0xb5,0x08,0x4b,
0x1b,0xb1,0x08,0x48,0x08,0x49,0xaf,0xf3,0x00,0x80,0x08,0x48,0x03,0x68,0x13,0xb9,
0xbd,0xe8,0x08,0x40,0xcc,0xe7,0x06,0x4b,0x00,0x2b,0xf9,0xd0,0x98,0x47,0xf7,0xe7,
0x00,0x00,0x00,0x00,0x3c,0x12,0x00,0x01,0x7c,0x16,0x00,0x01,0x34,0x24,0x00,0x20,
0x00,0x00,0x00,0x00,0x13,0x4b,0x00,0x2b,0x08,0xbf,0x11,0x4b,0x9d,0x46,0xa3,0xf5,
0x80,0x3a,0x00,0x21,0x8b,0x46,0x0f,0x46,0x11,0x48,0x12,0x4a,0x12,0x1a,0x00,0xf0,
0x79,0xf8,0x0d,0x4b,0x00,0x2b,0x00,0xd0,0x98,0x47,0x0c,0x4b,0x00,0x2b,0x00,0xd0,
0x98,0x47,0x00,0x20,0x00,0x21,0x04,0x00,0x0d,0x00,0x0b,0x48,0x00,0xf0,0x16,0xf8,
0x00,0xf0,0x40,0xf8,0x20,0x00,0x29,0x00,0x00,0xf0,0x04,0xff,0x00,0xf0,0x14,0xf8,
0x00,0x00,0x08,0x00,0x00,0x22,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x78,0x16,0x00,0x01,0x94,0x16,0x00,0x01,0xc9,0x02,0x00,0x01,0x01,0x46,0x00,0x20,
0x02,0x46,0x03,0x46,0x00,0xf0,0x9c,0xb8,0x08,0xb5,0x00,0x21,0x04,0x46,0x00,0xf0,
0xf3,0xf8,0x04,0x4b,0x18,0x68,0xc3,0x6b,0x03,0xb1,0x98,0x47,0x20,0x46,0x00,0xf0,
0x55,0xf9,0x00,0xbf,0x38,0x12,0x00,0x01,0x38,0xb5,0x08,0x4b,0x08,0x4d,0xed,0x1a,
0xac,0x10,0x18,0xbf,0xed,0x18,0x05,0xd0,0x01,0x3c,0x55,0xf8,0x04,0x3d,0x98,0x47,
0x00,0x2c,0xf9,0xd1,0xbd,0xe8,0x38,0x40,0x00,0xf0,0x9c,0xbf,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x70,0xb5,0x0f,0x4e,0x0f,0x4d,0x76,0x1b,0xb6,0x10,0x18,0xbf,
0x00,0x24,0x05,0xd0,0x01,0x34,0x55,0xf8,0x04,0x3b,0x98,0x47,0xa6,0x42,0xf9,0xd1,
0x0a,0x4e,0x0b,0x4d,0x76,0x1b,0x00,0xf0,0x7f,0xff,0xb6,0x10,0x18,0xbf,0x00,0x24,
0x06,0xd0,0x01,0x34,0x55,0xf8,0x04,0x3b,0x98,0x47,0xa6,0x42,0xf9,0xd1,0x70,0xbd,
0x70,0xbd,0x00,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x12,0x00,0x01,
0x10,0x12,0x00,0x01,0x70,0xb4,0x84,0x07,0x46,0xd0,0x54,0x1e,0x00,0x2a,0x41,0xd0,
0xcd,0xb2,0x03,0x46,0x02,0xe0,0x62,0x1e,0xe4,0xb3,0x14,0x46,0x03,0xf8,0x01,0x5b,
0x9a,0x07,0xf8,0xd1,0x03,0x2c,0x2e,0xd9,0xcd,0xb2,0x45,0xea,0x05,0x25,0x0f,0x2c,
0x45,0xea,0x05,0x45,0x19,0xd9,0x03,0xf1,0x10,0x02,0x26,0x46,0x10,0x3e,0x0f,0x2e,
0x42,0xf8,0x10,0x5c,0x42,0xf8,0x0c,0x5c,0x42,0xf8,0x08,0x5c,0x42,0xf8,0x04,0x5c,
0x02,0xf1,0x10,0x02,0xf2,0xd8,0xa4,0xf1,0x10,0x02,0x22,0xf0,0x0f,0x02,0x04,0xf0,
0x0f,0x04,0x10,0x32,0x03,0x2c,0x13,0x44,0x0d,0xd9,0x1e,0x46,0x22,0x46,0x04,0x3a,
0x03,0x2a,0x46,0xf8,0x04,0x5b,0xfa,0xd8,0x22,0x1f,0x22,0xf0,0x03,0x02,0x04,0x32,
0x13,0x44,0x04,0xf0,0x03,0x04,0x2c,0xb1,0xc9,0xb2,0x1c,0x44,0x03,0xf8,0x01,0x1b,
0xa3,0x42,0xfb,0xd1,0x70,0xbc,0x70,0x47,0x14,0x46,0x03,0x46,0xc2,0xe7,0x00,0xbf,
0x2d,0xe9,0xf0,0x47,0x25,0x4c,0x25,0x68,0xd5,0xf8,0x48,0x41,0x06,0x46,0x88,0x46,
0x92,0x46,0x99,0x46,0xcc,0xb3,0x60,0x68,0x1f,0x28,0x18,0xdc,0x43,0x1c,0x7e,0xb1,
0x04,0xeb,0x80,0x05,0x01,0x21,0xc5,0xf8,0x88,0xa0,0xd4,0xf8,0x88,0x71,0x01,0xfa,
0x00,0xf2,0x17,0x43,0x02,0x2e,0xc4,0xf8,0x88,0x71,0xc5,0xf8,0x08,0x91,0x1e,0xd0,
0x02,0x30,0x63,0x60,0x44,0xf8,0x20,0x80,0x00,0x20,0xbd,0xe8,0xf0,0x87,0x14,0x4b,
0x03,0xb3,0x4f,0xf4,0xc8,0x70,0xaf,0xf3,0x00,0x80,0x04,0x46,0xd0,0xb1,0xd5,0xf8,
0x48,0x31,0x00,0x27,0x80,0xe8,0x88,0x00,0xc5,0xf8,0x48,0x41,0x38,0x46,0x01,0x23,
0xc4,0xf8,0x88,0x71,0xc4,0xf8,0x8c,0x71,0x00,0x2e,0xe1,0xd0,0xd0,0xe7,0xd4,0xf8,
0x8c,0x11,0x0a,0x43,0xc4,0xf8,0x8c,0x21,0xda,0xe7,0x05,0xf5,0xa6,0x74,0xc5,0xf8,
0x48,0x41,0xc0,0xe7,0x4f,0xf0,0xff,0x30,0xbd,0xe8,0xf0,0x87,0x38,0x12,0x00,0x01,
0x00,0x00,0x00,0x00,0x02,0x4b,0x13,0xb1,0x02,0x48,0xff,0xf7,0x07,0xbf,0x70,0x47,
0x00,0x00,0x00,0x00,0xc9,0x02,0x00,0x01,0x2d,0xe9,0xf0,0x4f,0x31,0x4b,0x83,0xb0,
0x1b,0x68,0x00,0x93,0x03,0xf5,0xa4,0x73,0x81,0x46,0x0e,0x46,0x01,0x93,0x00,0x9b,
0xd3,0xf8,0x48,0x71,0x27,0xb3,0xdd,0xf8,0x04,0xa0,0x7c,0x68,0x65,0x1e,0x0e,0xd4,
0x01,0x34,0x07,0xeb,0x84,0x04,0x4f,0xf0,0x00,0x08,0xe6,0xb1,0xd4,0xf8,0x00,0x31,
0xb3,0x42,0x18,0xd0,0x01,0x3d,0x6b,0x1c,0xa4,0xf1,0x04,0x04,0xf5,0xd1,0x22,0x4b,
0x73,0xb1,0x7b,0x68,0x00,0x2b,0x36,0xd1,0x3b,0x68,0x00,0x2b,0x34,0xd0,0x38,0x46,
0xca,0xf8,0x00,0x30,0xaf,0xf3,0x00,0x80,0xda,0xf8,0x00,0x70,0x00,0x2f,0xdc,0xd1,
0x03,0xb0,0xbd,0xe8,0xf0,0x8f,0x7b,0x68,0x22,0x68,0x01,0x3b,0xab,0x42,0x0c,0xbf,
0x7d,0x60,0xc4,0xf8,0x00,0x80,0x00,0x2a,0xdc,0xd0,0xd7,0xf8,0x88,0x31,0xd7,0xf8,
0x04,0xb0,0x01,0x21,0xa9,0x40,0x19,0x42,0x08,0xd1,0x90,0x47,0x7b,0x68,0x5b,0x45,
0xbd,0xd1,0xda,0xf8,0x00,0x30,0xbb,0x42,0xcc,0xd0,0xb8,0xe7,0xd7,0xf8,0x8c,0x31,
0x19,0x42,0x04,0xd1,0x48,0x46,0xd4,0xf8,0x80,0x10,0x90,0x47,0xee,0xe7,0xd4,0xf8,
0x80,0x00,0x90,0x47,0xea,0xe7,0x3b,0x68,0xba,0x46,0x1f,0x46,0x00,0x2f,0xac,0xd1,
0xce,0xe7,0x00,0xbf,0x38,0x12,0x00,0x01,0x00,0x00,0x00,0x00,0xfe,0xe7,0x00,0xbf,
0x4f,0x4a,0x13,0x68,0xc3,0xf3,0x05,0x23,0x04,0x3b,0xdb,0xb2,0x15,0x2b,0x70,0xb4,
0x00,0xf2,0x8c,0x80,0x01,0x22,0x02,0xfa,0x03,0xf3,0x13,0xf0,0x30,0x1f,0x61,0xd0,
0x02,0x23,0x98,0x42,0x31,0xd0,0x46,0x4b,0x1b,0x68,0xc3,0xf3,0x05,0x23,0x44,0x4c,
0x44,0x49,0x01,0x25,0x22,0x68,0x09,0x2b,0x10,0xd8,0xdf,0xe8,0x03,0xf0,0x05,0x35,
0x0f,0x0f,0x45,0x29,0x0f,0x0f,0x45,0x29,0x01,0x28,0x63,0xd0,0x02,0x28,0x73,0xd1,
0x4f,0xf6,0xf0,0x76,0x3c,0x4b,0x16,0x40,0x33,0x43,0x23,0x60,0x0b,0x78,0x03,0xf0,
0xff,0x02,0x00,0x2b,0xfa,0xd1,0x23,0x68,0xc3,0xf3,0x05,0x23,0x04,0x3b,0xdb,0xb2,
0x15,0x2b,0x05,0xd8,0x05,0xfa,0x03,0xf3,0x13,0xf0,0x30,0x1f,0x38,0xd0,0x02,0x22,
0x23,0x68,0x90,0x42,0xc3,0xf3,0x05,0x23,0xd4,0xd1,0x01,0x20,0x70,0xbc,0x70,0x47,
0x4f,0xf6,0xf0,0x76,0x2d,0x4b,0x16,0x40,0x33,0x43,0x23,0x60,0x0b,0x78,0x03,0xf0,
0xff,0x02,0x00,0x2b,0xda,0xd1,0xde,0xe7,0x01,0x28,0x27,0xd0,0x02,0x28,0x43,0xd1,
0x4f,0xf6,0xf0,0x76,0x26,0x4b,0x16,0x40,0x33,0x43,0x23,0x60,0x0b,0x78,0x03,0xf0,
0xff,0x02,0x00,0x2b,0xca,0xd1,0xce,0xe7,0x4f,0xf6,0xf0,0x73,0x13,0x40,0x43,0xf0,
0xd2,0x43,0x43,0xf4,0xb4,0x03,0x23,0x60,0x0b,0x78,0x03,0xf0,0xff,0x02,0x00,0x2b,
0xbc,0xd1,0xc0,0xe7,0x13,0xf0,0x03,0x1f,0x14,0xbf,0x13,0x46,0x00,0x23,0x98,0xe7,
0x13,0xf0,0x03,0x1f,0x14,0xbf,0x01,0x22,0x00,0x22,0xc1,0xe7,0x4f,0xf6,0xf0,0x76,
0x14,0x4b,0x16,0x40,0x33,0x43,0x23,0x60,0x0b,0x78,0x03,0xf0,0xff,0x02,0x00,0x2b,
0xa4,0xd1,0xa8,0xe7,0x4f,0xf6,0xf0,0x76,0x0f,0x4b,0x16,0x40,0x33,0x43,0x23,0x60,
0x0b,0x78,0x03,0xf0,0xff,0x02,0x00,0x2b,0x98,0xd1,0x9c,0xe7,0x00,0x28,0xac,0xd0,
0x13,0x68,0xc3,0xf3,0x05,0x23,0x7a,0xe7,0x00,0x20,0x70,0xbc,0x70,0x47,0x00,0xbf,
0x00,0x00,0x01,0x40,0xa0,0x00,0x20,0x42,0x08,0x00,0x5a,0x69,0x01,0x00,0x5a,0x69,
0x09,0x00,0x5a,0x69,0x05,0x00,0x5a,0x69,0x04,0x00,0x5a,0x69,0x4a,0x4b,0x1b,0x68,
0xc3,0xf3,0x05,0x23,0x04,0x3b,0xdb,0xb2,0x15,0x2b,0xf0,0xb4,0x7e,0xd8,0x01,0x22,
0x02,0xfa,0x03,0xf3,0x13,0xf0,0x30,0x1f,0x5f,0xd0,0x02,0x26,0x42,0x4b,0x1b,0x68,
0xc3,0xf3,0x05,0x23,0x01,0x3b,0xdb,0xb2,0x1f,0x2b,0x69,0xd8,0x01,0x22,0x02,0xfa,
0x03,0xf3,0x03,0xf0,0x11,0x31,0x21,0xf0,0x10,0x21,0x00,0x29,0x68,0xd1,0x00,0x2b,
0xb4,0xbf,0x02,0x23,0x00,0x23,0x98,0x42,0x5d,0xd0,0x37,0x4c,0x37,0x49,0x01,0x25,
0x22,0x68,0x23,0x68,0xc3,0xf3,0x05,0x23,0x09,0x2b,0x0e,0xd8,0x05,0xfa,0x03,0xf3,
0x13,0xf4,0x89,0x7f,0x41,0xd1,0x40,0xf2,0x21,0x27,0x1f,0x40,0x2f,0xb1,0x4f,0xf6,
0xf0,0x77,0x2f,0x4b,0x17,0x40,0x3b,0x43,0x23,0x60,0x0b,0x78,0x03,0xf0,0xff,0x02,
0x00,0x2b,0xfa,0xd1,0x23,0x68,0xc3,0xf3,0x05,0x23,0x01,0x3b,0xdb,0xb2,0x1f,0x2b,
0x29,0xd8,0x05,0xfa,0x03,0xf3,0x03,0xf0,0x11,0x37,0x27,0xf0,0x10,0x27,0x6f,0xbb,
0x00,0x2b,0xb4,0xbf,0x02,0x23,0x00,0x23,0x98,0x42,0xd1,0xd1,0x1e,0x4b,0x1b,0x68,
0xc3,0xf3,0x05,0x23,0x04,0x3b,0xdb,0xb2,0x15,0x2b,0x06,0xd8,0x01,0x22,0x02,0xfa,
0x03,0xf3,0x13,0xf0,0x30,0x1f,0x25,0xd0,0x02,0x22,0x96,0x42,0x1b,0xd0,0x01,0x2e,
0x25,0xd0,0x02,0x20,0xf0,0xbc,0xff,0xf7,0xe3,0xbe,0x13,0xf0,0x03,0x1f,0x14,0xbf,
0x16,0x46,0x00,0x26,0x9a,0xe7,0x13,0x46,0xde,0xe7,0x4f,0xf6,0xf0,0x73,0x13,0x40,
0x43,0xf0,0xd2,0x43,0x43,0xf4,0xb4,0x03,0x23,0x60,0xbe,0xe7,0x01,0x23,0xd3,0xe7,
0x00,0x23,0x98,0x42,0xa1,0xd1,0x01,0x20,0xf0,0xbc,0x70,0x47,0x00,0x26,0x85,0xe7,
0x13,0x46,0x98,0xe7,0x13,0xf0,0x03,0x1f,0x08,0xbf,0x00,0x22,0xd5,0xe7,0x30,0x46,
0xf0,0xbc,0xff,0xf7,0xbd,0xbe,0x00,0xbf,0x00,0x00,0x01,0x40,0xa0,0x00,0x20,0x42,
0x01,0x00,0x5a,0x69,0xef,0xf3,0x10,0x80,0x72,0xb6,0x70,0x47,0x30,0xbf,0x70,0x47,
0x04,0x4a,0x08,0xb5,0x13,0x69,0x23,0xf0,0x04,0x03,0x13,0x61,0xff,0xf7,0xf6,0xff,
0x01,0x20,0x08,0xbd,0x00,0xed,0x00,0xe0,0xff,0xf7,0x50,0xbf,0x0b,0x4b,0x1b,0x68,
0xc3,0xf3,0x05,0x23,0x01,0x3b,0xdb,0xb2,0x1f,0x2b,0x0c,0xd8,0x01,0x20,0x00,0xfa,
0x03,0xf2,0x02,0xf0,0x11,0x33,0x23,0xf0,0x10,0x23,0x2b,0xb9,0x00,0x2a,0xb4,0xbf,
0x02,0x20,0x00,0x20,0x70,0x47,0x00,0x20,0x70,0x47,0x00,0xbf,0x00,0x00,0x01,0x40,
0x2d,0xe9,0xf8,0x43,0x7b,0x4e,0x7c,0x4c,0xdf,0xf8,0x00,0x82,0x7b,0x4f,0x7c,0x4d,
0x33,0x78,0x00,0x2b,0x43,0xd1,0x23,0x68,0x03,0xf0,0xf0,0x03,0xa0,0x2b,0x3e,0xd0,
0x23,0x68,0x03,0xf0,0xf0,0x03,0xc0,0x2b,0x39,0xd0,0x23,0x68,0xc3,0xf3,0x05,0x23,
0x04,0x3b,0xdb,0xb2,0x15,0x2b,0x08,0xd8,0x01,0x22,0x02,0xfa,0x03,0xf3,0x13,0xf0,
0x30,0x10,0x02,0xd1,0x13,0xf0,0x03,0x1f,0x55,0xd1,0x23,0x68,0xc3,0xf3,0x05,0x29,
0x22,0x68,0x4f,0xf6,0x0f,0x73,0x13,0x40,0x43,0xf0,0xd2,0x43,0x43,0xf4,0xb4,0x03,
0x23,0x60,0x2b,0x69,0x43,0xf0,0x04,0x03,0x2b,0x61,0xff,0xf7,0x9f,0xff,0x2b,0x69,
0x23,0xf0,0x04,0x03,0x2b,0x61,0x23,0x68,0xc3,0xf3,0x05,0x23,0x4b,0x45,0x29,0xd0,
0xb9,0xf1,0x11,0x0f,0x6b,0xd0,0x0d,0xd9,0xb9,0xf1,0x19,0x0f,0x72,0xd0,0x4b,0xd9,
0xb9,0xf1,0x21,0x0f,0x35,0xd0,0x02,0xd8,0xb9,0xf1,0x20,0x0f,0xb8,0xd0,0x00,0x20,
0xbd,0xe8,0xf8,0x83,0xb9,0xf1,0x05,0x0f,0x6f,0xd0,0x16,0xd9,0xb9,0xf1,0x09,0x0f,
0x00,0xf0,0x8c,0x80,0xb9,0xf1,0x10,0x0f,0x00,0xf0,0x81,0x80,0xb9,0xf1,0x08,0x0f,
0xed,0xd1,0x00,0x20,0xff,0xf7,0xd2,0xfe,0x98,0xb1,0x02,0x20,0xbd,0xe8,0xf8,0x43,
0xff,0xf7,0x1e,0xbe,0x01,0x20,0xbd,0xe8,0xf8,0x83,0xb9,0xf1,0x01,0x0f,0x68,0xd0,
0x5d,0xd3,0xb9,0xf1,0x04,0x0f,0xda,0xd1,0x00,0x20,0xff,0xf7,0xbf,0xfe,0x00,0x28,
0x50,0xd1,0xbd,0xe8,0xf8,0x83,0x23,0x68,0xc3,0xf3,0x05,0x29,0xff,0xf7,0x08,0xfe,
0xa6,0xe7,0x40,0x49,0x40,0x4a,0x8b,0x89,0x03,0xf0,0x7f,0x03,0x43,0xf4,0xb5,0x43,
0x8b,0x81,0x13,0x88,0xdb,0xb2,0x43,0xf4,0x25,0x43,0x01,0x20,0x00,0x21,0x13,0x80,
0x88,0xf8,0x00,0x00,0x39,0x70,0x72,0xe7,0xb9,0xf1,0x15,0x0f,0x5b,0xd0,0xb9,0xf1,
0x18,0x0f,0x51,0xd0,0xb9,0xf1,0x14,0x0f,0xb1,0xd1,0x00,0x20,0xff,0xf7,0x96,0xfe,
0x00,0x28,0xac,0xd0,0x01,0x20,0xff,0xf7,0xe3,0xfd,0x00,0x28,0xa7,0xd0,0x29,0x4b,
0x1b,0x78,0x00,0x2b,0xa3,0xd1,0xbd,0xe8,0xf8,0x43,0xff,0xf7,0x29,0xbf,0x01,0x20,
0xff,0xf7,0x84,0xfe,0x00,0x28,0x9a,0xd0,0x00,0x20,0xff,0xf7,0xd1,0xfd,0x00,0x28,
0xed,0xd1,0x94,0xe7,0x01,0x20,0xff,0xf7,0x79,0xfe,0x00,0x28,0x8f,0xd0,0x02,0x20,
0xff,0xf7,0xc6,0xfd,0x00,0x28,0xe2,0xd1,0x89,0xe7,0x01,0x20,0xff,0xf7,0x6e,0xfe,
0x00,0x28,0xae,0xd0,0x01,0x20,0xbd,0xe8,0xf8,0x43,0xff,0xf7,0xb9,0xbd,0x00,0x20,
0xff,0xf7,0x64,0xfe,0x00,0x28,0xa4,0xd0,0x00,0x20,0xbd,0xe8,0xf8,0x43,0xff,0xf7,
0xaf,0xbd,0x48,0x46,0xff,0xf7,0x5a,0xfe,0x00,0x28,0x9a,0xd0,0xf4,0xe7,0x00,0x20,
0xff,0xf7,0x54,0xfe,0x00,0x28,0x3f,0xf4,0x6a,0xaf,0xcd,0xe7,0x01,0x20,0xff,0xf7,
0x4d,0xfe,0x00,0x28,0x8d,0xd0,0x78,0xe7,0x00,0x20,0xff,0xf7,0x47,0xfe,0x00,0x28,
0x3f,0xf4,0x5d,0xaf,0xcb,0xe7,0x01,0x20,0xff,0xf7,0x40,0xfe,0x00,0x28,0x3f,0xf4,
0x56,0xaf,0xa7,0xe7,0xa0,0x00,0x20,0x42,0x00,0x00,0x01,0x40,0x20,0x80,0x08,0x42,
0x00,0xed,0x00,0xe0,0x00,0x48,0x00,0x40,0x00,0x44,0x00,0x40,0x58,0x80,0x08,0x42,
0x6b,0x49,0x30,0xb5,0x0a,0x68,0xc2,0xf3,0x05,0x22,0x90,0x42,0x83,0xb0,0x21,0xd0,
0x11,0x28,0x00,0xf0,0xbf,0x80,0x20,0xd9,0x19,0x28,0x00,0xf0,0x95,0x80,0x3a,0xd9,
0x21,0x28,0x5d,0xd0,0x55,0xd9,0xa0,0x28,0x00,0xf0,0x86,0x80,0xc0,0x28,0x1e,0xd1,
0x60,0x4b,0x1b,0x78,0xdb,0xb9,0x60,0x48,0x5d,0x49,0x02,0x69,0x5f,0x4b,0x42,0xf0,
0x04,0x02,0x02,0x61,0x08,0x68,0x4f,0xf6,0x0f,0x72,0x02,0x40,0x13,0x43,0x0b,0x60,
0xff,0xf7,0xa4,0xfe,0x01,0x20,0x03,0xb0,0x30,0xbd,0x05,0x28,0x00,0xf0,0xa1,0x80,
0x08,0xd9,0x09,0x28,0x62,0xd0,0x10,0x28,0x55,0xd0,0x08,0x28,0x4c,0xd0,0x00,0x20,
0x03,0xb0,0x30,0xbd,0x01,0x28,0x00,0xf0,0x87,0x80,0x7d,0xd3,0x04,0x28,0xf6,0xd1,
0x00,0x20,0xff,0xf7,0xeb,0xfd,0x00,0x28,0xe5,0xd0,0x01,0x20,0x03,0xb0,0xbd,0xe8,
0x30,0x40,0xff,0xf7,0x35,0xbd,0x15,0x28,0x67,0xd0,0x18,0x28,0x5f,0xd0,0x14,0x28,
0xe5,0xd1,0x00,0x20,0xff,0xf7,0xda,0xfd,0x00,0x28,0xe0,0xd0,0x01,0x20,0xff,0xf7,
0x27,0xfd,0x00,0x28,0xdb,0xd0,0x3f,0x4b,0x1b,0x78,0x00,0x2b,0xd7,0xd1,0x3e,0x4a,
0x01,0x90,0x13,0x69,0x23,0xf0,0x04,0x03,0x13,0x61,0xff,0xf7,0x67,0xfe,0x01,0x98,
0xc1,0xe7,0x20,0x28,0xcb,0xd1,0x03,0xb0,0xbd,0xe8,0x30,0x40,0xff,0xf7,0x88,0xbe,
0x37,0x49,0x38,0x4a,0x8b,0x89,0x38,0x4c,0x38,0x48,0x03,0xf0,0x7f,0x03,0x43,0xf4,
0xb5,0x43,0x8b,0x81,0x13,0x88,0xdb,0xb2,0x43,0xf4,0x25,0x43,0x01,0x25,0x00,0x21,
0x13,0x80,0x25,0x70,0x01,0x70,0xe6,0xe7,0x00,0x20,0xff,0xf7,0xa7,0xfd,0x00,0x28,
0xa1,0xd0,0x02,0x20,0xba,0xe7,0x00,0x20,0xff,0xf7,0xa0,0xfd,0x00,0x28,0xa6,0xd0,
0x00,0x20,0xff,0xf7,0xed,0xfc,0x00,0x28,0xc5,0xd1,0xa0,0xe7,0x01,0x20,0xff,0xf7,
0x95,0xfd,0x00,0x28,0x8f,0xd0,0xec,0xe7,0x1e,0x4b,0x1b,0x78,0x00,0x2b,0x96,0xd1,
0x1d,0x48,0x23,0x4b,0x02,0x69,0x7a,0xe7,0x01,0x20,0xff,0xf7,0x87,0xfd,0x00,0x28,
0x8d,0xd0,0x02,0x20,0xff,0xf7,0xd4,0xfc,0x00,0x28,0xac,0xd1,0x87,0xe7,0x00,0x20,
0xff,0xf7,0x7c,0xfd,0x00,0x28,0x82,0xd0,0xf3,0xe7,0x01,0x20,0xff,0xf7,0x76,0xfd,
0x00,0x28,0x3f,0xf4,0x7c,0xaf,0x99,0xe7,0x00,0x20,0xff,0xf7,0x6f,0xfd,0x00,0x28,
0x3f,0xf4,0x69,0xaf,0x00,0x20,0x81,0xe7,0xff,0xf7,0x68,0xfd,0x00,0x28,0x3f,0xf4,
0x62,0xaf,0xf7,0xe7,0x01,0x20,0xff,0xf7,0x61,0xfd,0x00,0x28,0x3f,0xf4,0x67,0xaf,
0xbe,0xe7,0x01,0x20,0xff,0xf7,0x5a,0xfd,0x00,0x28,0x3f,0xf4,0x54,0xaf,0x6c,0xe7,
0x00,0x00,0x01,0x40,0xa0,0x00,0x20,0x42,0x00,0xed,0x00,0xe0,0xa0,0x00,0x5a,0x69,
0x00,0x48,0x00,0x40,0x00,0x44,0x00,0x40,0x58,0x80,0x08,0x42,0x20,0x80,0x08,0x42,
0xc0,0x00,0x5a,0x69,0x02,0x4b,0x18,0x68,0xc0,0xf3,0x05,0x20,0x70,0x47,0x00,0xbf,
0x00,0x00,0x01,0x40,0x70,0xb5,0x1e,0x4e,0x1e,0x4a,0x33,0x68,0x1e,0x4d,0x1f,0x4c,
0x4f,0xf0,0x80,0x71,0x91,0x60,0x9b,0x6d,0x00,0x20,0x98,0x47,0x33,0x68,0x28,0x60,
0x9b,0x6d,0x01,0x20,0x98,0x47,0x68,0x60,0xff,0xf7,0xd8,0xfd,0x28,0x73,0xff,0xf7,
0xe1,0xff,0x63,0x68,0x68,0x73,0x03,0xf4,0xe0,0x23,0xab,0x60,0x00,0x20,0xff,0xf7,
0xef,0xfe,0x33,0x68,0x02,0x21,0x5b,0x6d,0x05,0x46,0x00,0x20,0x98,0x47,0x33,0x68,
0x01,0x20,0x5b,0x6d,0x02,0x21,0x98,0x47,0x46,0xf6,0x5a,0x13,0x23,0x60,0x63,0x68,
0x23,0xf4,0xe0,0x23,0x43,0xf4,0x80,0x23,0x00,0x22,0x63,0x60,0x22,0x60,0x08,0x4b,
0x1d,0xb1,0x40,0xf6,0xce,0x22,0x5a,0x60,0x70,0xbd,0x06,0x4a,0x5a,0x60,0x70,0xbd,
0x6c,0x08,0x00,0x02,0x00,0xed,0x00,0xe0,0x80,0x01,0x00,0x20,0x00,0x04,0x01,0x40,
0x50,0x01,0x00,0x20,0x00,0xad,0xde,0x00,0x19,0x4b,0xdb,0x69,0xda,0x07,0x70,0xb5,
0x1d,0xd4,0x17,0x4c,0xe3,0x69,0x9b,0x07,0x00,0xd4,0x70,0xbd,0x15,0x4d,0x16,0x49,
0x2b,0x68,0x4f,0xf4,0x00,0x10,0x1b,0x69,0x98,0x47,0x23,0x6a,0x0b,0x2b,0x19,0xd0,
0x12,0x4b,0x10,0x4a,0x1b,0x68,0x12,0x68,0x9b,0x6c,0x14,0x69,0x98,0x47,0x10,0x49,
0x23,0x46,0x01,0x44,0xbd,0xe8,0x70,0x40,0x4f,0xf4,0x01,0x10,0x18,0x47,0x0b,0x4b,
0x08,0x4a,0x1b,0x68,0x12,0x68,0x5b,0x68,0x14,0x69,0x98,0x47,0x41,0x1e,0x00,0x20,
0xa0,0x47,0xd6,0xe7,0x2b,0x68,0x06,0x49,0x1b,0x69,0x06,0x48,0x98,0x47,0xdf,0xe7,
0x50,0x01,0x00,0x20,0x6c,0x08,0x00,0x02,0xff,0x0f,0x20,0x00,0x68,0x08,0x00,0x02,
0xff,0x3f,0x20,0x00,0x00,0x20,0x20,0x00,0x14,0x4b,0x70,0xb5,0x14,0x4c,0x1b,0x68,
0x22,0x68,0x5b,0x68,0x15,0x69,0x98,0x47,0x41,0x1e,0x00,0x20,0xa8,0x47,0x23,0x68,
0x10,0x49,0x1b,0x69,0x4f,0xf4,0x00,0x10,0x98,0x47,0x0f,0x4b,0x1b,0x6a,0x0b,0x2b,
0x0e,0xd0,0x0a,0x4b,0x0a,0x4a,0x1b,0x68,0x12,0x68,0x9b,0x6c,0x14,0x69,0x98,0x47,
0x0a,0x49,0x23,0x46,0x01,0x44,0xbd,0xe8,0x70,0x40,0x4f,0xf4,0x01,0x10,0x18,0x47,
0x23,0x68,0x06,0x49,0x1b,0x69,0x06,0x48,0x98,0x47,0xea,0xe7,0x68,0x08,0x00,0x02,
0x6c,0x08,0x00,0x02,0xff,0x0f,0x20,0x00,0x50,0x01,0x00,0x20,0xff,0x3f,0x20,0x00,
0x00,0x20,0x20,0x00,0x2d,0xe9,0xf0,0x41,0xff,0xf7,0xc6,0xff,0x2d,0x49,0x4b,0x69,
0x2c,0x4a,0xdb,0x06,0xfb,0xd5,0x53,0x69,0x43,0xf0,0x01,0x03,0x53,0x61,0xd4,0x68,
0x15,0x69,0xb4,0xf5,0x00,0x1f,0x03,0xd2,0x2b,0x19,0xb3,0xf5,0x00,0x1f,0x2d,0xd8,
0x25,0x4b,0x1b,0x68,0x21,0x46,0x2a,0x46,0x9b,0x6a,0x4f,0xf0,0x20,0x20,0x98,0x47,
0x07,0x46,0x20,0x4c,0x21,0x4e,0x63,0x69,0x1f,0x4d,0x31,0x68,0x2a,0x68,0x23,0xf0,
0x11,0x03,0x63,0x61,0x4b,0x68,0xd2,0xf8,0x14,0x80,0x98,0x47,0x41,0x1e,0x00,0x20,
0xc0,0x47,0x33,0x68,0x2a,0x68,0x9b,0x6c,0x55,0x69,0x98,0x47,0x18,0x49,0x01,0x44,
0x4f,0xf4,0x00,0x10,0xa8,0x47,0x27,0xb1,0x40,0xf6,0xce,0x23,0x63,0x60,0xbd,0xe8,
0xf0,0x81,0x4d,0xf6,0xad,0x63,0x63,0x60,0xbd,0xe8,0xf0,0x81,0xdf,0xf8,0x38,0x80,
0xd8,0xf8,0x00,0x30,0xc4,0xf5,0x00,0x17,0x3a,0x46,0x9b,0x6a,0x21,0x46,0x4f,0xf0,
0x20,0x20,0x98,0x47,0xd8,0xf8,0x00,0x30,0x06,0x46,0xc4,0xf1,0x20,0x20,0xea,0x1b,
0x9b,0x6a,0x00,0xf5,0x00,0x10,0x4f,0xf4,0x00,0x11,0x98,0x47,0x30,0x40,0xc7,0xb2,
0xbf,0xe7,0x00,0xbf,0x50,0x01,0x00,0x20,0x6c,0x08,0x00,0x02,0x68,0x08,0x00,0x02,
0xff,0xff,0x1f,0x00,0x2d,0xe9,0xf0,0x4f,0x4f,0x4c,0x26,0x69,0xe7,0x68,0x83,0xb0,
0x00,0x2e,0x59,0xd0,0x4f,0xf0,0x00,0x09,0xca,0x46,0xcd,0xf8,0x00,0x90,0xb6,0xf5,
0x80,0x5f,0x93,0xbf,0xb0,0x46,0xa6,0xf5,0x80,0x56,0x4f,0xf4,0x80,0x58,0x00,0x26,
0xff,0xf7,0x4a,0xff,0x02,0xe0,0xa3,0x69,0xdb,0x06,0x02,0xd4,0x63,0x69,0xda,0x06,
0xf9,0xd5,0x65,0x69,0x15,0xf0,0x10,0x05,0x41,0xd0,0x63,0x69,0x43,0xf0,0x01,0x03,
0x63,0x61,0x4f,0xf0,0x20,0x2a,0x01,0x25,0x3c,0x4b,0x9f,0x42,0x08,0xeb,0x07,0x09,
0x3b,0x4b,0x02,0xd8,0xb9,0xf5,0x00,0x1f,0x4c,0xd8,0x1b,0x68,0x39,0x46,0x42,0x46,
0x9b,0x6a,0x50,0x46,0x98,0x47,0x4f,0x46,0x81,0x46,0x00,0x2d,0x39,0xd0,0x63,0x69,
0x23,0xf0,0x11,0x03,0x63,0x61,0xdf,0xf8,0xcc,0x80,0x31,0x4d,0xd8,0xf8,0x00,0x20,
0x2b,0x68,0x52,0x68,0xd3,0xf8,0x14,0xb0,0x90,0x47,0x41,0x1e,0x00,0x20,0xd8,0x47,
0xd8,0xf8,0x00,0x30,0x2a,0x68,0x9b,0x6c,0x55,0x69,0x98,0x47,0x27,0x49,0x01,0x44,
0x4f,0xf4,0x00,0x10,0xa8,0x47,0xb9,0xf1,0x00,0x0f,0x3e,0xd0,0x00,0x2e,0xae,0xd1,
0x21,0x4b,0x40,0xf6,0xce,0x22,0x5a,0x60,0x03,0xb0,0xbd,0xe8,0xf0,0x8f,0xa3,0x69,
0x13,0xf0,0x10,0x03,0x08,0xd0,0xa3,0x69,0xdf,0xf8,0x7c,0xa0,0x43,0xf0,0x01,0x03,
0xa3,0x61,0x01,0x23,0x00,0x93,0xb7,0xe7,0x00,0x9a,0x00,0x2a,0xcb,0xd0,0x1d,0x46,
0xb2,0xe7,0x00,0x9b,0x00,0x2b,0xc6,0xd0,0xa3,0x69,0x00,0x95,0x23,0xf0,0x11,0x03,
0xa3,0x61,0xc0,0xe7,0x1a,0x68,0x01,0x93,0xc7,0xf5,0x00,0x1b,0xd2,0xf8,0x28,0xc0,
0x39,0x46,0x5a,0x46,0x50,0x46,0xe0,0x47,0x01,0x9b,0x19,0x68,0x07,0x46,0xd1,0xf8,
0x28,0xc0,0xcb,0xeb,0x08,0x02,0x0a,0xeb,0x0b,0x00,0x4f,0xf4,0x00,0x11,0xe0,0x47,
0x38,0x40,0x4f,0x46,0x5f,0xfa,0x80,0xf9,0x9f,0xe7,0x03,0x4b,0x4d,0xf6,0xad,0x62,
0x5a,0x60,0x03,0xb0,0xbd,0xe8,0xf0,0x8f,0x50,0x01,0x00,0x20,0xff,0xff,0x1f,0x00,
0x6c,0x08,0x00,0x02,0x68,0x08,0x00,0x02,0x00,0x30,0x00,0x20,0x2d,0xe9,0xf0,0x41,
0x1b,0x4c,0x1c,0x4d,0x1c,0x4f,0x29,0x68,0x3a,0x68,0x46,0xf6,0x5a,0x18,0xc4,0xf8,
0x00,0x80,0x63,0x68,0x23,0xf4,0xe0,0x23,0x00,0x26,0x43,0xf4,0x80,0x33,0x63,0x60,
0x26,0x60,0x53,0x6d,0x30,0x46,0x98,0x47,0x3b,0x68,0x69,0x68,0x5b,0x6d,0x01,0x20,
0x98,0x47,0x68,0x7b,0xff,0xf7,0x1c,0xfd,0x07,0x46,0x28,0x7b,0xff,0xf7,0xf4,0xfb,
0xc4,0xf8,0x00,0x80,0x63,0x68,0xaa,0x68,0x0c,0x49,0x23,0xf4,0xe0,0x23,0x13,0x43,
0x63,0x60,0x26,0x60,0x0a,0x4b,0x8e,0x60,0x28,0xb1,0x27,0xb1,0x40,0xf6,0xce,0x22,
0x5a,0x60,0xbd,0xe8,0xf0,0x81,0x4d,0xf6,0xad,0x62,0x5a,0x60,0xbd,0xe8,0xf0,0x81,
0x00,0x04,0x01,0x40,0x80,0x01,0x00,0x20,0x6c,0x08,0x00,0x02,0x00,0xed,0x00,0xe0,
0x50,0x01,0x00,0x20,0x5b,0x4b,0x5c,0x4c,0x1b,0x68,0x5c,0x4e,0x1b,0x68,0x80,0xb5,
0x98,0x47,0xff,0xf7,0xb7,0xfb,0x27,0x46,0x23,0x68,0x20,0x2b,0x00,0xf2,0x99,0x80,
0x01,0xa2,0x52,0xf8,0x23,0xf0,0x00,0xbf,0x99,0x10,0x00,0x01,0x89,0x11,0x00,0x01,
0x65,0x11,0x00,0x01,0xd3,0x11,0x00,0x01,0x57,0x11,0x00,0x01,0xd3,0x11,0x00,0x01,
0xd3,0x11,0x00,0x01,0xd3,0x11,0x00,0x01,0x49,0x11,0x00,0x01,0xd3,0x11,0x00,0x01,
0xd3,0x11,0x00,0x01,0xd3,0x11,0x00,0x01,0xd3,0x11,0x00,0x01,0xd3,0x11,0x00,0x01,
0xd3,0x11,0x00,0x01,0xd3,0x11,0x00,0x01,0x3b,0x11,0x00,0x01,0xd3,0x11,0x00,0x01,
0xd3,0x11,0x00,0x01,0xd3,0x11,0x00,0x01,0xd3,0x11,0x00,0x01,0xd3,0x11,0x00,0x01,
0xd3,0x11,0x00,0x01,0xd3,0x11,0x00,0x01,0xd3,0x11,0x00,0x01,0xd3,0x11,0x00,0x01,
0xd3,0x11,0x00,0x01,0xd3,0x11,0x00,0x01,0xd3,0x11,0x00,0x01,0xd3,0x11,0x00,0x01,
0xd3,0x11,0x00,0x01,0xd3,0x11,0x00,0x01,0x2d,0x11,0x00,0x01,0x01,0x23,0x63,0x60,
0xff,0xf7,0xb8,0xfe,0x00,0x23,0x23,0x60,0xae,0xe7,0x01,0x23,0x63,0x60,0xff,0xf7,
0x5d,0xff,0x00,0x23,0x23,0x60,0xa7,0xe7,0x01,0x23,0x63,0x60,0xff,0xf7,0x82,0xfd,
0x00,0x23,0x23,0x60,0xa0,0xe7,0x01,0x23,0x63,0x60,0xff,0xf7,0x3b,0xfe,0x00,0x23,
0x23,0x60,0x99,0xe7,0x01,0x23,0x63,0x60,0xff,0xf7,0xfe,0xfd,0x05,0x25,0x33,0x68,
0xe0,0x68,0x5b,0x6a,0x98,0x47,0x01,0x3d,0x00,0x28,0x2e,0xd1,0x00,0x2d,0xf6,0xd1,
0x4d,0xf6,0xad,0x63,0x63,0x60,0x0d,0xe0,0x01,0x23,0x63,0x60,0xff,0xf7,0xac,0xfd,
0x05,0x25,0x33,0x68,0x1b,0x6a,0x98,0x47,0x01,0x3d,0x20,0xbb,0x00,0x2d,0xf8,0xd1,
0x17,0x4b,0x63,0x60,0x17,0x4d,0x32,0x68,0x2b,0x68,0xd2,0xf8,0x14,0x80,0x5b,0x68,
0x98,0x47,0x41,0x1e,0x00,0x20,0xc0,0x47,0x2b,0x68,0x32,0x68,0x9b,0x6c,0x55,0x69,
0x98,0x47,0x11,0x49,0x01,0x44,0x4f,0xf4,0x00,0x10,0xa8,0x47,0x00,0x23,0x23,0x60,
0x62,0xe7,0x40,0xf6,0xad,0x33,0x63,0x60,0x5e,0xe7,0x00,0x2d,0xd0,0xd0,0x40,0xf6,
0xce,0x23,0x7b,0x60,0xde,0xe7,0x00,0x2d,0xda,0xd0,0x40,0xf6,0xce,0x23,0x63,0x60,
0xd8,0xe7,0x00,0xbf,0x64,0x08,0x00,0x02,0x50,0x01,0x00,0x20,0x6c,0x08,0x00,0x02,
0xad,0xde,0xad,0xde,0x68,0x08,0x00,0x02,0xff,0xff,0x1f,0x00,0xfe,0xe7,0x00,0xbf,
0xfd,0x01,0x00,0x01,0x85,0x04,0x00,0x01,0xf8,0xb5,0x00,0xbf,0xf8,0xbc,0x08,0xbc,
0x9e,0x46,0x70,0x47,0xf8,0xb5,0x00,0xbf,0xd5,0x01,0x00,0x01,0xf8,0xbc,0x08,0xbc,
0x9e,0x46,0x70,0x47,0x43,0x00,0x00,0x00,0x08,0x20,0x00,0x20,0xf8,0xef,0xff,0x7f,
0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0xf4,0x22,0x00,0x20,0x5c,0x23,0x00,0x20,0xc4,0x23,0x00,0x20,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x34,0x12,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0e,0x33,0xcd,0xab,
0x34,0x12,0x6d,0xe6,0xec,0xde,0x05,0x00,0x0b,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x08,0x20,0x00,0x20,

View File

@ -0,0 +1,122 @@
/******************************************************************************
*
* Copyright (C) 2017-2018 Texas Instruments Incorporated - http://www.ti.com/
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* distribution.
*
* Neither the name of Texas Instruments Incorporated nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************/
#include <stdint.h>
/* Entry point for the application. */
extern int main();
/* Reserve space for the system stack. */
extern uint32_t __stack_top;
typedef void(*pFunc)(void);
/* Interrupt handler prototypes */
void default_handler(void);
void reset_handler(void);
/*
* The vector table. Note that the proper constructs must be placed on this to
* ensure that it ends up at physical address 0x0000.0000 or at the start of
* the program if located at a start address other than 0.
*/
void (* const intr_vectors[])(void) __attribute__((section(".intvecs"))) = {
(pFunc)&__stack_top, /* The initial stack pointer */
reset_handler, /* The reset handler */
default_handler, /* The NMI handler */
default_handler, /* The hard fault handler */
default_handler, /* The MPU fault handler */
default_handler, /* The bus fault handler */
default_handler, /* The usage fault handler */
0, /* Reserved */
0, /* Reserved */
0, /* Reserved */
0, /* Reserved */
default_handler, /* SVCall handler */
default_handler, /* Debug monitor handler */
0, /* Reserved */
default_handler, /* The PendSV handler */
default_handler /* The SysTick handler */
};
/*
* The following are constructs created by the linker, indicating where the
* the "data" and "bss" segments reside in memory. The initializers for the
* for the "data" segment resides immediately following the "text" segment.
*/
extern uint32_t __bss_start__;
extern uint32_t __bss_end__;
/*
* This is the code that gets called when the processor first starts execution
* following a reset event. Only the absolutely necessary set is performed,
* after which the application supplied entry() routine is called. Any fancy
* actions (such as making decisions based on the reset cause register, and
* resetting the bits in that register) are left solely in the hands of the
* application.
*/
__attribute__((section(".reset"))) __attribute__((naked))
void reset_handler(void)
{
/* Set stack pointer */
__asm(" MOVW.W r0, #0x1700\n"
" MOVT.W r0, #0x2000\n"
" mov sp, r0\n");
/* Zero fill the bss segment. */
__asm(" ldr r0, =__bss_start__\n"
" ldr r1, =__bss_end__\n"
" mov r2, #0\n"
" .thumb_func\n"
"zero_loop:\n"
" cmp r0, r1\n"
" it lt\n"
" strlt r2, [r0], #4\n"
" blt zero_loop");
/* Call the application's entry point. */
main();
}
/*
* This is the code that gets called when the processor receives an unexpected
* interrupt. This simply enters an infinite loop, preserving the system state
* for examination by a debugger.
*/
void default_handler(void)
{
/* Enter an infinite loop. */
while (1)
;
}

View File

@ -0,0 +1,122 @@
/******************************************************************************
*
* Copyright (C) 2012-2018 Texas Instruments Incorporated - http://www.ti.com/
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* distribution.
*
* Neither the name of Texas Instruments Incorporated nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************/
#include <stdint.h>
/* Entry point for the application. */
extern int main();
/* Reserve space for the system stack. */
extern uint32_t __stack_top;
typedef void(*pFunc)(void);
/* Interrupt handler prototypes */
void default_handler(void);
void reset_handler(void);
/*
* The vector table. Note that the proper constructs must be placed on this to
* ensure that it ends up at physical address 0x0000.0000 or at the start of
* the program if located at a start address other than 0.
*/
void (* const intr_vectors[])(void) __attribute__((section(".intvecs"))) = {
(pFunc)&__stack_top, /* The initial stack pointer */
reset_handler, /* The reset handler */
default_handler, /* The NMI handler */
default_handler, /* The hard fault handler */
default_handler, /* The MPU fault handler */
default_handler, /* The bus fault handler */
default_handler, /* The usage fault handler */
0, /* Reserved */
0, /* Reserved */
0, /* Reserved */
0, /* Reserved */
default_handler, /* SVCall handler */
default_handler, /* Debug monitor handler */
0, /* Reserved */
default_handler, /* The PendSV handler */
default_handler /* The SysTick handler */
};
/*
* The following are constructs created by the linker, indicating where the
* the "data" and "bss" segments reside in memory. The initializers for the
* for the "data" segment resides immediately following the "text" segment.
*/
extern uint32_t __bss_start__;
extern uint32_t __bss_end__;
/*
* This is the code that gets called when the processor first starts execution
* following a reset event. Only the absolutely necessary set is performed,
* after which the application supplied entry() routine is called. Any fancy
* actions (such as making decisions based on the reset cause register, and
* resetting the bits in that register) are left solely in the hands of the
* application.
*/
__attribute__((section(".reset"))) __attribute__((naked))
void reset_handler(void)
{
/* Set stack pointer */
__asm(" MOVW.W r0, #0x1700\n"
" MOVT.W r0, #0x0100\n"
" mov sp, r0\n");
/* Zero fill the bss segment. */
__asm(" ldr r0, =__bss_start__\n"
" ldr r1, =__bss_end__\n"
" mov r2, #0\n"
" .thumb_func\n"
"zero_loop:\n"
" cmp r0, r1\n"
" it lt\n"
" strlt r2, [r0], #4\n"
" blt zero_loop");
/* Call the application's entry point. */
main();
}
/*
* This is the code that gets called when the processor receives an unexpected
* interrupt. This simply enters an infinite loop, preserving the system state
* for examination by a debugger.
*/
void default_handler(void)
{
/* Enter an infinite loop. */
while (1)
;
}

View File

@ -13,9 +13,7 @@
* 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, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
/*

View File

@ -28,7 +28,7 @@ An additional function, quit, is added to the remote_bitbang interface to
indicate there will be no more requests and the connection with the remote
driver should be closed.
These five functions are encoded in ascii by assigning a single character to
These five functions are encoded in ASCII by assigning a single character to
each possible request. The assignments are:
B - Blink on
@ -48,6 +48,6 @@ each possible request. The assignments are:
t - Reset 1 0
u - Reset 1 1
The read response is encoded in ascii as either digit 0 or 1.
The read response is encoded in ASCII as either digit 0 or 1.
*/

View File

@ -123,7 +123,7 @@ implement new checks.
The <code>make distcheck</code> command produces an archive of the
project deliverables (using <code>make dist</code>) and verifies its
integrity for distribution by attemptng to use the package in the same
integrity for distribution by attempting to use the package in the same
manner as a user.
These checks includes the following steps:

View File

@ -30,7 +30,7 @@ called (with the appropriate parameters), the @c CALL_COMMAND_HANDLER
macro to pass any e as parameters to the following helper function:
The subsequent blocks of code are a normal C function that can do
anything, so only complex commands deserve should use comamnd helper
anything, so only complex commands deserve should use command helper
functions. In this respect, this example uses one to demonstrate how --
not when -- they should be used.

View File

@ -19,7 +19,7 @@ OpenOCD presently produces several kinds of documentation:
- See @subpage primerlatex and @ref stylelatex.
- The Manual:
- Focuses on developing the OpenOCD software.
- Details the architecutre, driver interfaces, and processes.
- Details the architecture, driver interfaces, and processes.
- Provides "full" coverage of C source code (work-in-progress).
- Written using Doxygen C language conventions (i.e. in comments).
- Created with 'make doxygen'.

View File

@ -125,7 +125,7 @@ There is some tricky things going on.
===============
First, there is a "for" loop - at level 0
{level 0 means: out side of a proc/function}
{level 0 means: outside of a procedure/function}
This means it is evaluated when the file is parsed.
@ -151,9 +151,9 @@ The FOR command:
5) Goto Step 2.
As show, each of these items are in {curly-braces}. This means they
are passed as they are - KEY-POINT: un evaluated to the FOR
are passed as they are - KEY-POINT: unevaluated to the FOR
command. Think of it like escaping the backticks in Bash so that the
"under-lying" command can evaluate the contents. In this case, the FOR
"underlying" command can evaluate the contents. In this case, the FOR
COMMAND.
== END: SIDEBAR: About The FOR command ==
@ -167,9 +167,9 @@ Format is like "sprintf". Because of the [brackets], it becomes what
you think. But here's how:
First - the line is parsed - for {braces}. In this case, there are
none. The, the parser looks for [brackets] and finds them. The,
none. Then, the parser looks for [brackets] and finds them. The
parser then evaluates the contents of the [brackets], and replaces
them. It is alot this bash statement.
them. It is similar to this bash statement.
EXPORT vn=`date`
@ -179,7 +179,7 @@ LINE 2 & 3
In line 1, we dynamically created a variable name. Here, we are
assigning it a value. Lastly Line 3 we force the variable to be
global, not "local" the the "for command body"
global, not "local" within the "for command body"
===============
The PROCS
@ -194,7 +194,7 @@ The (1) NAME of the function, a (2) LIST of parameters, and a (3) BODY
Again, this is at "level 0" so it is a global function. (Yes, TCL
supports local functions, you put them inside of a function}
You'll see in some cases, I nest [brackets] alot and in others I'm
You'll see in some cases, I nest [brackets] a lot and in others I'm
lazy or wanted it to be more clear... it is a matter of choice.
===============
@ -224,7 +224,7 @@ All memory regions must have 2 things:
RWX - the access ability.
WIDTH - the accessible width.
ie: Some regions of memory are not 'word'
i.e.: Some regions of memory are not 'word'
accessible.
The function "address_info" - given an address should
@ -287,7 +287,7 @@ Notice this IF COMMAND - (not statement) is like this:
error [format string...]
}
The "IF" command expects either 2 params, or 4 params.
The "IF" command expects either 2 or 4 parameters.
=== Sidebar: About "commands" ===
@ -317,7 +317,7 @@ You give CATCH 1 or 2 parameters.
The 2nd (optional) is where to put the error message.
CATCH returns 0 on success, 1 for failure.
The "![catch command]" is self explaintory.
The "![catch command]" is self explanatory.
The 3rd parameter to IF must be exactly "else" or "elseif" [I lied
@ -341,7 +341,7 @@ exists. {the function: "proc_exists" does this}
And - if it does - I call the function.
In "C" it is alot like using: 'sprintf()' to construct a function name
In "C" it is a lot like using: 'sprintf()' to construct a function name
string, then using "dlopen()" and "dlsym()" to look it up - and get a
function pointer - and calling the function pointer.
@ -380,7 +380,7 @@ Some assumptions:
The "CHIP" file has defined some variables in a proper form.
ie: AT91C_BASE_US0 - for usart0,
i.e.: AT91C_BASE_US0 - for usart0,
AT91C_BASE_US1 - for usart1
... And so on ...
@ -394,7 +394,7 @@ looks like this:
In this case, I'm trying to figure out what USARTs exist.
Step 1 - is to determine if the NAME has been defined.
ie: Does AT91C_BASE_USx - where X is some number exist?
i.e.: Does AT91C_BASE_USx - where X is some number exist?
The "info exists VARNAME" tells you if the variable exists. Then -
inside the IF statement... There is another loop. This loop is the

View File

@ -36,7 +36,7 @@ several important advantages compared to using the source repository
were produced as part of creating the archive.
-# Because they have been formally released by the project, users
don't need to try a random work-in-process revision. Releasing
involves spending some time specifically on quality improvments,
involves spending some time specifically on quality improvements,
including bugfixing source code and documentation.
-# They provide developers with the flexibility needed to address
larger issues, which sometimes involves temporary breakage.
@ -149,7 +149,7 @@ specific git revisions:
0.3.0-rc1-dev-00015-gf37c9b8-dirty
indicates a development tree based on git revison f37c9b8
indicates a development tree based on git revision f37c9b8
(a truncated version of a SHA1 hash) with some non-git
patches applied (the <em>dirty</em> tag). This information
can be useful when tracking down bugs.
@ -385,7 +385,7 @@ git tag -m "The openocd-${PACKAGE_VERSION} release." "${PACKAGE_TAG}"
- Last updates for the release, including the release tag (you
will need to "git push --tags").
- Updates opening the merge window
- At this point, it's OK for commiters to start pushing changes
- At this point, it's OK for committers to start pushing changes
which have been held off until the next release. (Any bugfixes to
this release will be against a bug-fix release branch starting from
the commit you tagged as this release, not mainline.)
@ -423,7 +423,7 @@ tools/release.sh --type=micro branch
Both of these variations make automatic commits and tags in your
repository, so you should be sure to run it on a cloned copy before
proceding with a live release.
proceeding with a live release.
@subsection releasescriptopts Release Script Options

View File

@ -43,7 +43,7 @@ Default implementation of procedures in tcl/procedures.tcl.
functions constitute the tcl api. flash_banks is such
a low level tcl proc. "flash banks" is an example of
a command that has human readable output. The human
readable output is expected to change inbetween versions
readable output is expected to change in between versions
of OpenOCD. The output from flash_banks may not be
in the preferred form for the client. The client then
has two choices a) parse the output from flash_banks

View File

@ -29,7 +29,7 @@ write new code and creates a support nightmare.
In many ways, people had talked about the need for some type of
high-level interface to OpenOCD, because they only had two choices:
- the ability to script: via an external program the actions of OpenOCD.
- the ablity to write a complex internal commands: native 'commands'
- the ability to write a complex internal commands: native 'commands'
inside of OpenOCD was complicated.
Fundamentally, the basic problem with both of those would be solved
@ -68,7 +68,7 @@ interfaces well with TCL.
From there, the developers wanted to create an external front-end that
would be @a very usable and that that @a any language could utilize,
allowing simple front-ends to be (a) cross-platform (b) languag
allowing simple front-ends to be (a) cross-platform (b) language
agnostic, and (c) easy to develop and use.
Simple ASCII protocols are easy. For example, HTTP, FTP (control), and
@ -76,7 +76,7 @@ SMTP are all text-based. All of these examples are widely and
well-known, and they do not require high-speed or high-volume. They
also support a high degree of interoperability with multiple systems.
They are not human-centric protocols; more correctly, they are rigid,
terse, simple ASCII protocols that are emensely parsable by a script.
terse, simple ASCII protocols that are easily parsable by a script.
Thus, the TCL server -- a 'machine' type socket interface -- was added
with the hope was it would output simple "name-value" pair type
@ -95,25 +95,25 @@ and do things with it!
A lot has been said about various "widigit-foo-gui-library is so
wonderful". Please refer back to the domino and spider web problem of
dependencies. Sure, you may well know the WhatEver-GUI library, but
most others will not (including the next contributer to OpenOCD).
most others will not (including the next contributor to OpenOCD).
How do we solve that problem?
For example, Cygwin can be painful, Cygwin GUI packages want X11
to be present, crossing the barrier between MinGW and Cygwin is
painful, let alone getting the GUI front end to work on MacOS, and
Linux, yuck yuck yuck. Painful. very very painful.
Linux, yuck yuck yuck. Painful, very very painful.
What works easier and is less work is what is already present in every
platform? The answer: A web browser. In other words, OpenOCD could
serve out embedded web pages via "localhost" to your browser.
Long before OpenOCD had a TCL command line, Zylin AS built their ZY1000
devince with a built-in HTTP server. Later, they were willing to both
device with a built-in HTTP server. Later, they were willing to both
contribute and integrate most of that work into the main tree.
@subsection serverdocsother Other Options Considered
What if a web browser is not acceptable ie: You want to write your own
What if a web browser is not acceptable i.e.: You want to write your own
front gadget in Eclipse, or KDevelop, or PerlTK, Ruby, or what ever
the latest and greatest Script De Jour is.
@ -134,7 +134,7 @@ taking over OpenOCD. His concern is and was: how do you debug
something written in 2 different languages? A "SWIG" front-end is
unlikely to help that situation.
@subsection serverdoccombined Combined: Socket & WebServer Benifits
@subsection serverdoccombined Combined: Socket & WebServer Benefits
Seriously think about this question: What script language (or compiled
language) today cannot talk directly to a socket? Every thing in the
@ -146,23 +146,23 @@ and serve it out via the embedded web server, could it - or something
like it talk to the built in TCL server? Yes, absolutely! We are on to
something here.
@subsection serverdocplatforms Platform Permuntations
@subsection serverdocplatforms Platform Permutations
Look at some permutations where OpenOCD can run; these "just work" if
the Socket Approach is used.
- Linux/Cygwin/MinGw/MacOSx/FreeBSD development Host Locally
- Linux/Cygwin/MinGW/MacOSX/FreeBSD development Host Locally
- OpenOCD with some dongle on that host
- Linux/Cygwin/MingW/MacOS/FreeBSD development host
- DONGLE: tcpip based ARM-Linux perhaps at91rm9200 or ep93xx.c, running openocd.
- Linux/Cygwin/MinGW/MacOS/FreeBSD development host
- DONGLE: TCP/IP based ARM-Linux perhaps at91rm9200 or ep93xx.c, running openocd.
- Windows cygwin/X desktop environment.
- Windows Cygwin/X desktop environment.
- Linux development host (via remote X11)
- Dongle: "eb93xx.c" based linux board
- Dongle: "eb93xx.c" based Linux board
@subsection serverdocfuture Development Scale Out
@ -214,8 +214,8 @@ love or attention. Perhaps it will after you read and understand this.
One reason might be, this adds one more host side requirement to make
use of the feature. In other words, one could write a Python/TK
front-end, but it is only useable if you have Python/TK installed.
Maybe this can be done via Ecllipse, but not all developers use Ecplise.
Many devlopers use Emacs (possibly with GUD mode) or vim and will not
Maybe this can be done via Eclipse, but not all developers use Eclipse.
Many developers use Emacs (possibly with GUD mode) or vim and will not
accept such an interface. The next developer reading this might be
using Insight (GDB-TK) - and somebody else - DDD..
@ -260,7 +260,7 @@ OS) is another example.
One could create a simple: <b>Click here to display memory</b> or maybe
<b>click here to display the UART REGISTER BLOCK</b>; click again and see
each register explained in exquisit detail.
each register explained in exquisite detail.
For an STM32, one could create a simple HTML page, with simple
substitution text that the simple web server use to substitute the
@ -269,7 +269,7 @@ memory. We end up with an HTML page that could list the contents of
every peripheral register on the target platform.
That also is transportable, regardless of the OpenOCD host
platform: Linux/X86, Linux/ARM, FreeBSD, Cygwin, MingW, or MacOSX.
platform: Linux/X86, Linux/ARM, FreeBSD, Cygwin, MinGW, or MacOSX.
You could even port OpenOCD to an Android system and use it as a
bit-banging JTAG Adapter serving web pages.

View File

@ -112,7 +112,7 @@ pthreads require modest and predictable stack usage.
@section stylefunc Functions
- static inline functions should be prefered over macros:
- static inline functions should be preferred over macros:
@code
/** do NOT define macro-like functions like this... */
#define CUBE(x) ((x) * (x) * (x))
@ -201,7 +201,7 @@ The following guidelines apply to all Doxygen comment blocks:
-# @c struct_name::member_name should be used to reference structure
fields in the documentation (e.g. @c flash_driver::name).
-# URLS get converted to markup automatically, without any extra effort.
-# new pages can be linked into the heirarchy by using the @c \@subpage
-# new pages can be linked into the hierarchy by using the @c \@subpage
command somewhere the page(s) under which they should be linked:
-# use @c \@ref in other contexts to create links to pages and sections.
-# Use good Doxygen mark-up:
@ -233,7 +233,7 @@ documentation as part of standalone text files:
- Doxygen creates such pages for files automatically, but no content
will appear on them for those that only contain manual pages.
- The \@file block should provide useful meta-documentation to assist
techincal writers; typically, a list of the pages that it contains.
technical writers; typically, a list of the pages that it contains.
- For example, the @ref styleguide exists in @c doc/manual/style.txt,
which contains a reference back to itself.
-# The \@file and \@page commands should begin on the same line as
@ -261,7 +261,7 @@ The User's Guide is there to provide two basic kinds of information. It
is a guide for how and why to use each feature or mechanism of OpenOCD.
It is also the reference manual for all commands and options involved
in using them, including interface, flash, target, and other drivers.
At this time, it is the only user-targetted documentation; everything
At this time, it is the only documentation for end users; everything
else is addressing OpenOCD developers.
There are two key audiences for the User's Guide, both developer based.

View File

@ -46,14 +46,14 @@ This value is defined only when a processor access is pending.
Processor will do the action for us : it can for example read internal state (register values),
and send us back the information via EJTAG memory (dmseg), or it can take some data from dmseg and write it into the registers or RAM.
Every time when it sees address (i.e. when this address is the part of the opcode it is executing, wether it is instruction or data fetch)
that falls into dmseg, processor stalls. That acutally meand that CPU stops it's pipeline and it is waitning for dongle to take some action.
Every time when it sees address (i.e. when this address is the part of the opcode it is executing, whether it is instruction or data fetch)
that falls into dmseg, processor stalls. That actually means that CPU stops it's pipeline and it is waiting for dongle to take some action.
CPU is now either waiting for dongle to take some data from dmseg (if we requested for CPU do give us internal state, for example),
or it will wait for some data from dongle (if it needs following instruction because it did previous, or if the operand address of the currently executed opcode
falls somewhere (anywhere) in dmseg (0xff..ff20000 - 0xff..ff2fffff)).
Bit PNnW describes character of CPU access to EJTAG memory (the memry where dongle puts/takes data) - CPU can either READ for it (PNnW == 0) or
Bit PNnW describes character of CPU access to EJTAG memory (the memory where dongle puts/takes data) - CPU can either READ for it (PNnW == 0) or
WRITE to it (PNnW == 1).
By reading PNnW bit OpenOCD will know if it has to send (PNnW == 0) or to take (PNnW == 1) data (from dmseg, via dongle).
@ -79,7 +79,7 @@ OpenOCD can figure out which action has to be taken by reading PrAcc bit.
Once action from dongle has been done, i.e. after the data is taken/put, OpenOCD can signal to CPU to proceed with executing the instruction.
This can be the next instruction (if previous was finished before pending), or the same instruction - if for example CPU was waiting on dongle
to give it an operand, because it saw in the instruction opcode that operand address is somewhere in dmseg. That prowoked the CPU to stall (it tried operand fetch to dmseg and stopped),
to give it an operand, because it saw in the instruction opcode that operand address is somewhere in dmseg. That provoked the CPU to stall (it tried operand fetch to dmseg and stopped),
and PNnW bit is 0 (CPU does read from dmseg), and PrAcc is 1 (CPU is pending on dmseg access).
@subsection spracc SPrAcc
@ -155,16 +155,16 @@ static const uint32_t code[] = {
We have to pass this code to CPU via dongle via dmseg.
After debug exception CPU will find itself stalling at the begining of the dmseg. It waits for the first instruction from dongle.
After debug exception CPU will find itself stalling at the beginning of the dmseg. It waits for the first instruction from dongle.
This is MIPS32_MTC0(15,31,0), so CPU saves C0 and continues to addr 0xFF20 0001, which falls also to dmseg, so it stalls.
Dongle proceeds giving to CPU one by one instruction in this manner.
However, things are not so simple. If you take a look at the program, you will see that some instructions take operands. If it has to take
operand from the address in dmseg, CPU will stall witing for the dongle to do the action of passing the operand and signal this by putting PrAcc to 0.
If this operand is somewhere in RAM, CPU will not stall (it stalls only on dmseg), but it will just take it and proceed to nex instruction. But since PC for next instruction
operand from the address in dmseg, CPU will stall waiting for the dongle to do the action of passing the operand and signal this by putting PrAcc to 0.
If this operand is somewhere in RAM, CPU will not stall (it stalls only on dmseg), but it will just take it and proceed to next instruction. But since PC for next instruction
points to dmseg, it will stall, so that dongle can pass next instruction.
Some instuctions are jumps (if these are jumps in dmseg addr, CPU will jump and then stall. If this is jump to some address in RAM, CPU will jump and just proceed -
Some instructions are jumps (if these are jumps in dmseg addr, CPU will jump and then stall. If this is jump to some address in RAM, CPU will jump and just proceed -
will not stall on addresses in RAM).
To have information about CPU is currently (does it stalls wanting on operand or it jumped somewhere waiting for next instruction),
@ -213,10 +213,10 @@ else
@endcode
i.e. if CPU is stalling on addresses in dmseg that are reserved for input parameters, we can conclude that it actually tried to take (read)
parametar from there, and saw that address of param falls in dmseg, so it stopped. Obviously, now dongle have to give to it operand.
parameter from there, and saw that address of parameter falls in dmseg, so it stopped. Obviously, now dongle have to give to it operand.
Similarly, mips32_pracc_exec_write() describes CPU writes into EJTAG memory (dmseg).
Obvioulsy, code is RO, and CPU can change only parameters :
Obviously, code is RO, and CPU can change only parameters :
@code
mips_ejtag_set_instr(ctx->ejtag_info, EJTAG_INST_DATA);
@ -331,10 +331,10 @@ uint32_t handler_code[] = {
};
@endcode
In the begining and the end of the handler we have fuction prologue (save the regs that will be clobbered) and epilogue (restore regs),
In the beginning and the end of the handler we have function prologue (save the regs that will be clobbered) and epilogue (restore regs),
and in the very end, after all the xfer have been done, we do jump to the MIPS32_PRACC_TEXT address, i.e. Debug Exception Vector location.
We will use this fact (that we came back to MIPS32_PRACC_TEXT) to verify later if all the handler is executed (because when in RAM,
processor do not stall - it executes all instructions untill one of them do not demand access to dmseg (if one of it's opernads is there)).
processor do not stall - it executes all instructions until one of them do not demand access to dmseg (if one of it's operands is there)).
This handler is put into the RAM and executed from there, and not instruction by instruction, like in previous simple write
(mips_m4k_write_memory()) and read (mips_m4k_read_memory()) functions.
@ -347,12 +347,12 @@ MIPS32_LW(9,0,8) /* start addr in t1 */
and there it will stall - because it will see that one of the operands have to be fetched from dmseg (EJTAG memory, in this case FASTDATA memory segment).
This handler is loaded in the RAM, ath the reserved location "work_area". This work_area is configured in OpenOCD configuration script and should be selected
This handler is loaded in the RAM, at the reserved location "work_area". This work_area is configured in OpenOCD configuration script and should be selected
in that way that it is not clobbered (overwritten) by data we want to write-in using FASTDATA.
What is executed instruction by instruction which is passed by dongle (via EJATG memory) is small jump code, which jumps at the handler in RAM.
CPU stalls on dmseg when receiving these jmp_code instructions, but once it jumps in RAM, CPU do not stall anymore and executes bunch of handler instructions.
Untill it comes to the first instruction which has an operand in FASTDATA area. There it stalls and waits on action from probe.
Until it comes to the first instruction which has an operand in FASTDATA area. There it stalls and waits on action from probe.
It happens actually when CPU comes to this loop :
@code
@ -393,15 +393,15 @@ for (i = 0; i < count; i++)
}
@endcode
Each time when OpenOCD fills data to CPU (via dongle, via dmseg), CPU takes it and proceeds in executing the endler. However, since handler is in a assembly loop,
Each time when OpenOCD fills data to CPU (via dongle, via dmseg), CPU takes it and proceeds in executing the handler. However, since handler is in a assembly loop,
CPU comes to next instruction which also fetches data from FASTDATA area. So it stalls.
Then OpenOCD fills the data again, from it's (OpenOCD's) loop. And this game continues untill all the data has been filled.
After the last data has beend given to CPU it sees that it reached the end address, so it proceeds with next instruction. However, rhis instruction do not point into dmseg, so
After the last data has been given to CPU it sees that it reached the end address, so it proceeds with next instruction. However, this instruction do not point into dmseg, so
CPU executes bunch of handler instructions (all prologue) and in the end jumps to MIPS32_PRACC_TEXT address.
On it's side, OpenOCD checks in CPU has jumped back to MIPS32_PRACC_TEXT, which is the confirmation that it correclty executed all the rest of the handler in RAM,
and that is not stuck somewhere in the RAM, or stalling on some acces in dmseg - that would be an error :
On it's side, OpenOCD checks in CPU has jumped back to MIPS32_PRACC_TEXT, which is the confirmation that it correctly executed all the rest of the handler in RAM,
and that is not stuck somewhere in the RAM, or stalling on some access in dmseg - that would be an error :
@code
address = 0;
@ -462,7 +462,7 @@ Download flow (probe -> target block transfer) :
Note: A failure may have a recoverable (and even expected) cause like slow target execution of the load loop. Other failures may be due to unexpected more troublesome causes like an exception while in debug mode or a target hang on a bad target memory access.
Shifted out SPrAcc bit inform us that there was CPU access pendingand that it can be complete.
Shifted out SPrAcc bit inform us that there was CPU access pending and that it can be complete.
Basically, we should do following procedure :
@ -497,7 +497,7 @@ by checking SPrAcc that we shifted out.
If some FASTDATA write fails, OpenOCD will continue with it's loop (on the host side), but CPU will rest pending (on the target side)
waiting for correct FASTDATA write.
Since OpenOCD goes ahead, it will eventually finish it's loop, and proceede to check if CPU took all the data. But since CPU did not took all the data,
Since OpenOCD goes ahead, it will eventually finish it's loop, and proceed to check if CPU took all the data. But since CPU did not took all the data,
it is still turns in handler's loop in RAM, stalling on Fastdata area so this check :
@code
@ -513,24 +513,24 @@ if (address != MIPS32_PRACC_TEXT)
fails, and that gives us enough information of the failure.
In this case, we can lower the JTAG frquency and try again, bacuse most probable reason of this failure is that we tried FASTDATA upload before CPU arrived to rise PrAcc (i.e. before it was pending on access).
In this case, we can lower the JTAG frequency and try again, because most probable reason of this failure is that we tried FASTDATA upload before CPU arrived to rise PrAcc (i.e. before it was pending on access).
However, the reasons for failure might be numerous : reset, exceptions which can occur in debug mode, bus hangs, etc.
If lowering the JTAG freq does not work either, we can fall back to more robust solution with patch posted below.
To summarize, FASTDATA communication goes as following :
-# CPU jumps to Debug Exception Vector Location 0xFF200200 in dmseg and it stalls, pending and waiting for EJTAG to give it first debug instruction and signall it by putting PrAcc to "0"
-# CPU jumps to Debug Exception Vector Location 0xFF200200 in dmseg and it stalls, pending and waiting for EJTAG to give it first debug instruction and signal it by putting PrAcc to "0"
-# When PrAcc goes to "0" CPU execute one opcode sent by EJTAG via DATA reg. Then it pends on next access, waiting for PrAcc to be put to "0" again
-# Following this game, OpenOCD first loads handler code in RAM, and then sends the jmp_code - instruction by instruction via DATA reg, which redirects CPU to handler previously set up in RAM
-# Once in RAM CPU does not pend on any instruction, but it executes all handler instructions untill first "fetch" to Fastdata area - then it stops and pends.
-# Once in RAM CPU does not pend on any instruction, but it executes all handler instructions until first "fetch" to Fastdata area - then it stops and pends.
-# So - when it comes to any instruction (opcode) in this handler in RAM which reads (or writes) to Fastdata area (0xF..F20.0000 to 0xF..F20.000F), CPU stops (i.e. stalls access).
I.e. it stops on this lw opcode and waits to FASTDATA TAP command from the probe.
-# CPU continues only if OpenOCD shifted in SPrAcc "0" (and if the PrAcc was "1"). It shifts-out "1" to tell us that it was OK (processor was stalled, so it can complete the access),
and that it continued execution of the handler in RAM.
-# If PrAcc was not "1" CPU will not continue (go to next instruction), but will shift-out "0" and keep stalling on the same instruction of my handler in RAM.
-# When Fastdata loop is finished, CPU executes all following hadler instructions in RAM (prologue).
-# In the end of my handler in RAM, I jumps back to begining of Debug Exception Vector Location 0xFF200200 in dmseg.
-# When Fastdata loop is finished, CPU executes all following handler instructions in RAM (prologue).
-# In the end of my handler in RAM, I jumps back to beginning of Debug Exception Vector Location 0xFF200200 in dmseg.
-# When it jumps back to 0xFF200200 in dmseg processor stops and pends, waiting for OpenOCD to send it instruction via DATA reg and signal it by putting PrAcc to "0".
*/

View File

@ -59,7 +59,7 @@ of the total OpenOCD system.
@section targetnotarmppc PowerPC
there exists open source implementations of powerpc
there exists open source implementations of PowerPC
target manipulation, but there hasn't been a lot
of activity in the mailing list.

View File

@ -531,6 +531,12 @@ debuggers to ARM Cortex based targets @url{http://www.keil.com/support/man/docs/
@item @b{Keil ULINK v1}
@* Link: @url{http://www.keil.com/ulink1/}
@item @b{TI XDS110 Debug Probe}
@* The XDS110 is included as the embedded debug probe on many Texas Instruments
LaunchPad evaluation boards.
@* Link: @url{http://processors.wiki.ti.com/index.php/XDS110}
@* Link: @url{http://processors.wiki.ti.com/index.php/XDS_Emulation_Software_Package#XDS110_Support_Utilities}
@end itemize
@section IBM PC Parallel Printer Port Based
@ -4081,6 +4087,18 @@ or set a new value @var{value}.
Select AP @var{num}, defaulting to 0.
@end deffn
@deffn Command {$dap_name dpreg} reg [value]
Displays the content of DP register at address @var{reg}, or set it to a new
value @var{value}.
In case of SWD, @var{reg} is a value in packed format
@math{dpbanksel << 4 | addr} and assumes values 0, 4, 8 ... 0xfc.
In case of JTAG it only assumes values 0, 4, 8 and 0xc.
@emph{Note:} Consider using @command{poll off} to avoid any disturbing
background activity by OpenOCD while you are operating at such low-level.
@end deffn
@deffn Command {$dap_name baseaddr} [num]
Displays debug base address from MEM-AP @var{num},
defaulting to the currently selected AP.
@ -4423,7 +4441,7 @@ The value should normally correspond to a static mapping for the
@item @code{-rtos} @var{rtos_type} -- enable rtos support for target,
@var{rtos_type} can be one of @option{auto}, @option{eCos},
@option{ThreadX}, @option{FreeRTOS}, @option{linux}, @option{ChibiOS},
@option{embKernel}, @option{mqx}, @option{uCOS-III}
@option{embKernel}, @option{mqx}, @option{uCOS-III}, @option{nuttx}
@xref{gdbrtossupport,,RTOS Support}.
@item @code{-defer-examine} -- skip target examination at initial JTAG chain
@ -5569,7 +5587,32 @@ flash erase_sector 0 0 127 # It will perform a mass erase on BlueNRG-2
@end example
Triggering a mass erase is also useful when users want to disable readout protection.
@end deffn
@deffn {Flash Driver} cc26xx
All versions of the SimpleLink CC13xx and CC26xx microcontrollers from Texas
Instruments include internal flash. The cc26xx flash driver supports both the
CC13xx and CC26xx family of devices. The driver automatically recognizes the
specific version's flash parameters and autoconfigures itself. Flash bank 0
starts at address 0.
@example
flash bank $_FLASHNAME cc26xx 0 0 0 0 $_TARGETNAME
@end example
@end deffn
@deffn {Flash Driver} cc3220sf
The CC3220SF version of the SimpleLink CC32xx microcontrollers from Texas
Instruments includes 1MB of internal flash. The cc3220sf flash driver only
supports the internal flash. The serial flash on SimpleLink boards is
programmed via the bootloader over a UART connection. Security features of
the CC3220SF may erase the internal flash during power on reset. Refer to
documentation at @url{www.ti.com/cc3220sf} for details on security features
and programming the serial flash.
@example
flash bank $_FLASHNAME cc3220sf 0 0 0 0 $_TARGETNAME
@end example
@end deffn
@deffn {Flash Driver} efm32
@ -5969,6 +6012,41 @@ if @{ [info exists IMEMORY] && [string equal $IMEMORY true] @} @{
@end example
@end deffn
@deffn {Flash Driver} msp432
All versions of the SimpleLink MSP432 microcontrollers from Texas
Instruments include internal flash. The msp432 flash driver automatically
recognizes the specific version's flash parameters and autoconfigures itself.
Main program flash (starting at address 0) is flash bank 0. Information flash
region on MSP432P4 versions (starting at address 0x200000) is flash bank 1.
@example
flash bank $_FLASHNAME msp432 0 0 0 0 $_TARGETNAME
@end example
@deffn Command {msp432 mass_erase} [main|all]
Performs a complete erase of flash. By default, @command{mass_erase} will erase
only the main program flash.
On MSP432P4 versions, using @command{mass_erase all} will erase both the
main program and information flash regions. To also erase the BSL in information
flash, the user must first use the @command{bsl} command.
@end deffn
@deffn Command {msp432 bsl} [unlock|lock]
On MSP432P4 versions, @command{bsl} unlocks and locks the bootstrap loader (BSL)
region in information flash so that flash commands can erase or write the BSL.
Leave the BSL locked to prevent accidentally corrupting the bootstrap loader.
To erase and program the BSL:
@example
msp432 bsl unlock
flash erase_address 0x202000 0x2000
flash write_image bsl.bin 0x202000
msp432 bsl lock
@end example
@end deffn
@end deffn
@deffn {Flash Driver} niietcm4
This drivers handles the integrated NOR flash on NIIET Cortex-M4
based controllers. Flash size and sector layout are auto-configured by the driver.
@ -6122,6 +6200,68 @@ The @var{num} parameter is a value shown by @command{flash banks}.
@end deffn
@end deffn
@deffn {Flash Driver} psoc5lp
All members of the PSoC 5LP microcontroller family from Cypress
include internal program flash and use ARM Cortex-M3 cores.
The driver probes for a number of these chips and autoconfigures itself,
apart from the base address.
@example
flash bank $_FLASHNAME psoc5lp 0x00000000 0 0 0 $_TARGETNAME
@end example
@b{Note:} PSoC 5LP chips can be configured to have ECC enabled or disabled.
@quotation Attention
If flash operations are performed in ECC-disabled mode, they will also affect
the ECC flash region. Erasing a 16k flash sector in the 0x00000000 area will
then also erase the corresponding 2k data bytes in the 0x48000000 area.
Writing to the ECC data bytes in ECC-disabled mode is not implemented.
@end quotation
Commands defined in the @var{psoc5lp} driver:
@deffn Command {psoc5lp mass_erase}
Erases all flash data and ECC/configuration bytes, all flash protection rows,
and all row latches in all flash arrays on the device.
@end deffn
@end deffn
@deffn {Flash Driver} psoc5lp_eeprom
All members of the PSoC 5LP microcontroller family from Cypress
include internal EEPROM and use ARM Cortex-M3 cores.
The driver probes for a number of these chips and autoconfigures itself,
apart from the base address.
@example
flash bank $_CHIPNAME.eeprom psoc5lp_eeprom 0x40008000 0 0 0 $_TARGETNAME
@end example
@end deffn
@deffn {Flash Driver} psoc5lp_nvl
All members of the PSoC 5LP microcontroller family from Cypress
include internal Nonvolatile Latches and use ARM Cortex-M3 cores.
The driver probes for a number of these chips and autoconfigures itself.
@example
flash bank $_CHIPNAME.nvl psoc5lp_nvl 0 0 0 0 $_TARGETNAME
@end example
PSoC 5LP chips have multiple NV Latches:
@itemize
@item Device Configuration NV Latch - 4 bytes
@item Write Once (WO) NV Latch - 4 bytes
@end itemize
@b{Note:} This driver only implements the Device Configuration NVL.
The @var{psoc5lp} driver reads the ECC mode from Device Configuration NVL.
@quotation Attention
Switching ECC mode via write to Device Configuration NVL will require a reset
after successful write.
@end quotation
@end deffn
@deffn {Flash Driver} psoc6
Supports PSoC6 (CY8C6xxx) family of Cypress microcontrollers.
PSoC6 is a dual-core device with CM0+ and CM4 cores. Both cores share
@ -7262,6 +7402,19 @@ Useful in connection with script files
Close the OpenOCD server, disconnecting all clients (GDB, telnet,
other). If option @option{error} is used, OpenOCD will return a
non-zero exit code to the parent process.
Like any TCL commands, also @command{shutdown} can be redefined, e.g.:
@example
# redefine shutdown
rename shutdown original_shutdown
proc shutdown @{@} @{
puts "This is my implementation of shutdown"
# my own stuff before exit OpenOCD
original_shutdown
@}
@end example
If user types CTRL-C or kills OpenOCD, either the command @command{shutdown}
or its replacement will be automatically executed before OpenOCD exits.
@end deffn
@anchor{debuglevel}
@ -8086,6 +8239,30 @@ interacting with remote files or displaying console messages in the
debugger.
@end deffn
@deffn Command {arm semihosting_resexit} [@option{enable}|@option{disable}]
@cindex ARM semihosting
Enable resumable SEMIHOSTING_SYS_EXIT.
When SEMIHOSTING_SYS_EXIT is called outside a debug session,
things are simple, the openocd process calls exit() and passes
the value returned by the target.
When SEMIHOSTING_SYS_EXIT is called during a debug session,
by default execution returns to the debugger, leaving the
debugger in a HALT state, similar to the state entered when
encountering a break.
In some use cases, it is useful to have SEMIHOSTING_SYS_EXIT
return normally, as any semihosting call, and do not break
to the debugger.
The standard allows this to happen, but the condition
to trigger it is a bit obscure ("by performing an RDI_Execute
request or equivalent").
To make the SEMIHOSTING_SYS_EXIT call return normally, enable
this option (default: disabled).
@end deffn
@section ARMv4 and ARMv5 Architecture
@cindex ARMv4
@cindex ARMv5
@ -8623,8 +8800,8 @@ Enable or disable trace output for all ITM stimulus ports.
@deffn Command {cortex_m maskisr} (@option{auto}|@option{on}|@option{off})
Control masking (disabling) interrupts during target step/resume.
The @option{auto} option handles interrupts during stepping a way they get
served but don't disturb the program flow. The step command first allows
The @option{auto} option handles interrupts during stepping in a way that they
get served but don't disturb the program flow. The step command first allows
pending interrupt handlers to execute, then disables interrupts and steps over
the next instruction where the core was halted. After the step interrupts
are enabled again. If the interrupt handlers don't complete within 500ms,
@ -8794,6 +8971,95 @@ Display all registers in @emph{group}.
"timer" or any new group created with addreg command.
@end deffn
@section RISC-V Architecture
@uref{http://riscv.org/, RISC-V} is a free and open ISA. OpenOCD supports JTAG
debug of RV32 and RV64 cores in heterogeneous multicore systems of up to 32
harts. (It's possible to increase this limit to 1024 by changing
RISCV_MAX_HARTS in riscv.h.) OpenOCD primarily supports 0.13 of the RISC-V
Debug Specification, but there is also support for legacy targets that
implement version 0.11.
@subsection RISC-V Terminology
A @emph{hart} is a hardware thread. A hart may share resources (eg. FPU) with
another hart, or may be a separate core. RISC-V treats those the same, and
OpenOCD exposes each hart as a separate core.
@subsection RISC-V Debug Configuration Commands
@deffn Command {riscv expose_csrs} n0[-m0][,n1[-m1]]...
Configure a list of inclusive ranges for CSRs to expose in addition to the
standard ones. This must be executed before `init`.
By default OpenOCD attempts to expose only CSRs that are mentioned in a spec,
and then only if the corresponding extension appears to be implemented. This
command can be used if OpenOCD gets this wrong, or a target implements custom
CSRs.
@end deffn
@deffn Command {riscv expose_csrs} n0[-m0][,n1[-m1]]...
The RISC-V Debug Specification allows targets to expose custom registers
through abstract commands. (See Section 3.5.1.1 in that document.) This command
configures a list of inclusive ranges of those registers to expose. Number 0
indicates the first custom register, whose abstract command number is 0xc000.
This command must be executed before `init`.
@end deffn
@deffn Command {riscv set_command_timeout_sec} [seconds]
Set the wall-clock timeout (in seconds) for individual commands. The default
should work fine for all but the slowest targets (eg. simulators).
@end deffn
@deffn Command {riscv set_reset_timeout_sec} [seconds]
Set the maximum time to wait for a hart to come out of reset after reset is
deasserted.
@end deffn
@deffn Command {riscv set_scratch_ram} none|[address]
Set the address of 16 bytes of scratch RAM the debugger can use, or 'none'.
This is used to access 64-bit floating point registers on 32-bit targets.
@end deffn
@deffn Command {riscv set_prefer_sba} on|off
When on, prefer to use System Bus Access to access memory. When off, prefer to
use the Program Buffer to access memory.
@end deffn
@subsection RISC-V Authentication Commands
The following commands can be used to authenticate to a RISC-V system. Eg. a
trivial challenge-response protocol could be implemented as follows in a
configuration file, immediately following @command{init}:
@example
set challenge [ocd_riscv authdata_read]
riscv authdata_write [expr $challenge + 1]
@end example
@deffn Command {riscv authdata_read}
Return the 32-bit value read from authdata. Note that to get read value back in
a TCL script, it needs to be invoked as @command{ocd_riscv authdata_read}.
@end deffn
@deffn Command {riscv authdata_write} value
Write the 32-bit value to authdata.
@end deffn
@subsection RISC-V DMI Commands
The following commands allow direct access to the Debug Module Interface, which
can be used to interact with custom debug features.
@deffn Command {riscv dmi_read}
Perform a 32-bit DMI read at address, returning the value. Note that to get
read value back in a TCL script, it needs to be invoked as @command{ocd_riscv
dmi_read}.
@end deffn
@deffn Command {riscv dmi_write} address value
Perform a 32-bit DMI write of value at address.
@end deffn
@anchor{softwaredebugmessagesandtracing}
@section Software Debug Messages and Tracing
@cindex Linux-ARM DCC support
@ -9551,6 +9817,7 @@ Currently supported rtos's include:
@item @option{embKernel}
@item @option{mqx}
@item @option{uCOS-III}
@item @option{nuttx}
@end itemize
@quotation Note
@ -9586,6 +9853,8 @@ Rtos::sListSuspended, Rtos::sMaxPriorities, Rtos::sCurrentTaskCount.
_mqx_kernel_data, MQX_init_struct.
@item uC/OS-III symbols
OSRunning, OSTCBCurPtr, OSTaskDbgListPtr, OSTaskQty
@item nuttx symbols
g_readytorun, g_tasklisttable
@end table
For most RTOS supported the above symbols will be exported by default. However for

View File

@ -19,6 +19,8 @@ NOR_DRIVERS = \
%D%/atsamv.c \
%D%/avrf.c \
%D%/bluenrg-x.c \
%D%/cc3220sf.c \
%D%/cc26xx.c \
%D%/cfi.c \
%D%/dsp5680xx_flash.c \
%D%/efm32.c \
@ -35,6 +37,7 @@ NOR_DRIVERS = \
%D%/lpc2900.c \
%D%/lpcspifi.c \
%D%/mdr.c \
%D%/msp432.c \
%D%/mrvlqspi.c \
%D%/niietcm4.c \
%D%/non_cfi.c \
@ -43,6 +46,7 @@ NOR_DRIVERS = \
%D%/ocl.c \
%D%/pic32mx.c \
%D%/psoc4.c \
%D%/psoc5lp.c \
%D%/psoc6.c \
%D%/sim3x.c \
%D%/spi.c \
@ -64,9 +68,12 @@ NOR_DRIVERS = \
NORHEADERS = \
%D%/core.h \
%D%/cc3220sf.h \
%D%/cc26xx.h \
%D%/cfi.h \
%D%/driver.h \
%D%/imp.h \
%D%/non_cfi.h \
%D%/ocl.h \
%D%/spi.h
%D%/spi.h \
%D%/msp432.h

View File

@ -682,6 +682,40 @@ static const struct sam4_chip_details all_sam4_details[] = {
},
},
},
/*at91sam4sa16c - TFBGA100/VFBGA100/LQFP100*/
{
.chipid_cidr = 0x28a70ce0,
.name = "at91sam4sa16c",
.total_flash_size = 1024 * 1024,
.total_sram_size = 160 * 1024,
.n_gpnvms = 2,
.n_banks = 1,
/* .bank[0] = { */
{
{
.probed = 0,
.pChip = NULL,
.pBank = NULL,
.bank_number = 0,
.base_address = FLASH_BANK_BASE_S,
.controller_address = 0x400e0a00,
.flash_wait_states = 5,
.present = 1,
.size_bytes = 1024 * 1024,
.nsectors = 128,
.sector_size = 8192,
.page_size = 512,
},
/* .bank[1] = {*/
{
.present = 0,
.probed = 0,
.bank_number = 1,
},
},
},
/*atsam4s16b - LQFP64/QFN64/WLCSP64*/
{
.chipid_cidr = 0x289C0CE0,
@ -1243,50 +1277,6 @@ static const struct sam4_chip_details all_sam4_details[] = {
.page_size = 512,
},
/* .bank[1] = { */
{
.probed = 0,
.pChip = NULL,
.pBank = NULL,
.bank_number = 1,
.base_address = FLASH_BANK1_BASE_1024K_SD,
.controller_address = 0x400e0c00,
.flash_wait_states = 5,
.present = 1,
.size_bytes = 512 * 1024,
.nsectors = 64,
.sector_size = 8192,
.page_size = 512,
},
},
},
/*at91sam4sa16c*/
{
.chipid_cidr = 0x28a70ce0,
.name = "at91sam4sa16c",
.total_flash_size = 1024 * 1024,
.total_sram_size = 160 * 1024,
.n_gpnvms = 3,
.n_banks = 2,
/* .bank[0] = { */
{
{
.probed = 0,
.pChip = NULL,
.pBank = NULL,
.bank_number = 0,
.base_address = FLASH_BANK0_BASE_SD,
.controller_address = 0x400e0a00,
.flash_wait_states = 5,
.present = 1,
.size_bytes = 512 * 1024,
.nsectors = 64,
.sector_size = 8192,
.page_size = 512,
},
/* .bank[1] = { */
{
.probed = 0,
@ -2554,6 +2544,8 @@ static int sam4_GetDetails(struct sam4_bank_private *pPrivate)
pPrivate->pChip->cfg.CHIPID_CIDR);
sam4_explain_chipid_cidr(pPrivate->pChip);
return ERROR_FAIL;
} else {
LOG_INFO("SAM4 Found chip %s, CIDR 0x%08x", pDetails->name, pDetails->chipid_cidr);
}
/* DANGER: THERE ARE DRAGONS HERE */
@ -2624,6 +2616,7 @@ static int _sam4_probe(struct flash_bank *bank, int noise)
for (x = 0; x < SAM4_MAX_FLASH_BANKS; x++) {
if (bank->base == pPrivate->pChip->details.bank[x].base_address) {
bank->size = pPrivate->pChip->details.bank[x].size_bytes;
LOG_INFO("SAM4 Set flash bank to %08X - %08X, idx %d", bank->base, bank->base + bank->size, x);
break;
}
}

View File

@ -115,15 +115,16 @@ static const struct samd_part samd10_parts[] = {
/* Known SAMD11 parts */
static const struct samd_part samd11_parts[] = {
{ 0x0, "SAMD11D14AMU", 16, 4 },
{ 0x0, "SAMD11D14AM", 16, 4 },
{ 0x1, "SAMD11D13AMU", 8, 4 },
{ 0x2, "SAMD11D12AMU", 4, 4 },
{ 0x3, "SAMD11D14ASU", 16, 4 },
{ 0x3, "SAMD11D14ASS", 16, 4 },
{ 0x4, "SAMD11D13ASU", 8, 4 },
{ 0x5, "SAMD11D12ASU", 4, 4 },
{ 0x6, "SAMD11C14A", 16, 4 },
{ 0x7, "SAMD11C13A", 8, 4 },
{ 0x8, "SAMD11C12A", 4, 4 },
{ 0x9, "SAMD11D14AU", 16, 4 },
};
/* Known SAMD20 parts. See Table 12-8 in 42129FSAM10/2013 */

567
src/flash/nor/cc26xx.c Normal file
View File

@ -0,0 +1,567 @@
/***************************************************************************
* Copyright (C) 2017 by Texas Instruments, Inc. *
* *
* 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 2 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/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "imp.h"
#include "cc26xx.h"
#include <helper/binarybuffer.h>
#include <helper/time_support.h>
#include <target/algorithm.h>
#include <target/armv7m.h>
#include <target/image.h>
#define FLASH_TIMEOUT 8000
struct cc26xx_bank {
const char *family_name;
uint32_t icepick_id;
uint32_t user_id;
uint32_t device_type;
uint32_t sector_length;
bool probed;
struct working_area *working_area;
struct armv7m_algorithm armv7m_info;
const uint8_t *algo_code;
uint32_t algo_size;
uint32_t algo_working_size;
uint32_t buffer_addr[2];
uint32_t params_addr[2];
};
static int cc26xx_auto_probe(struct flash_bank *bank);
static uint32_t cc26xx_device_type(uint32_t icepick_id, uint32_t user_id)
{
uint32_t device_type = 0;
switch (icepick_id & ICEPICK_ID_MASK) {
case CC26X0_ICEPICK_ID:
device_type = CC26X0_TYPE;
break;
case CC26X1_ICEPICK_ID:
device_type = CC26X1_TYPE;
break;
case CC13X0_ICEPICK_ID:
device_type = CC13X0_TYPE;
break;
case CC13X2_CC26X2_ICEPICK_ID:
default:
if ((user_id & USER_ID_CC13_MASK) != 0)
device_type = CC13X2_TYPE;
else
device_type = CC26X2_TYPE;
break;
}
return device_type;
}
static uint32_t cc26xx_sector_length(uint32_t icepick_id)
{
uint32_t sector_length;
switch (icepick_id & ICEPICK_ID_MASK) {
case CC26X0_ICEPICK_ID:
case CC26X1_ICEPICK_ID:
case CC13X0_ICEPICK_ID:
/* Chameleon family device */
sector_length = CC26X0_SECTOR_LENGTH;
break;
case CC13X2_CC26X2_ICEPICK_ID:
default:
/* Agama family device */
sector_length = CC26X2_SECTOR_LENGTH;
break;
}
return sector_length;
}
static int cc26xx_wait_algo_done(struct flash_bank *bank, uint32_t params_addr)
{
struct target *target = bank->target;
struct cc26xx_bank *cc26xx_bank = bank->driver_priv;
uint32_t status_addr = params_addr + CC26XX_STATUS_OFFSET;
uint32_t status = CC26XX_BUFFER_FULL;
long long start_ms;
long long elapsed_ms;
int retval = ERROR_OK;
start_ms = timeval_ms();
while (CC26XX_BUFFER_FULL == status) {
retval = target_read_u32(target, status_addr, &status);
if (ERROR_OK != retval)
return retval;
elapsed_ms = timeval_ms() - start_ms;
if (elapsed_ms > 500)
keep_alive();
if (elapsed_ms > FLASH_TIMEOUT)
break;
};
if (CC26XX_BUFFER_EMPTY != status) {
LOG_ERROR("%s: Flash operation failed", cc26xx_bank->family_name);
return ERROR_FAIL;
}
return ERROR_OK;
}
static int cc26xx_init(struct flash_bank *bank)
{
struct target *target = bank->target;
struct cc26xx_bank *cc26xx_bank = bank->driver_priv;
int retval;
/* Make sure we've probed the flash to get the device and size */
retval = cc26xx_auto_probe(bank);
if (ERROR_OK != retval)
return retval;
/* Check for working area to use for flash helper algorithm */
if (NULL != cc26xx_bank->working_area)
target_free_working_area(target, cc26xx_bank->working_area);
retval = target_alloc_working_area(target, cc26xx_bank->algo_working_size,
&cc26xx_bank->working_area);
if (ERROR_OK != retval)
return retval;
/* Confirm the defined working address is the area we need to use */
if (CC26XX_ALGO_BASE_ADDRESS != cc26xx_bank->working_area->address)
return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
/* Write flash helper algorithm into target memory */
retval = target_write_buffer(target, CC26XX_ALGO_BASE_ADDRESS,
cc26xx_bank->algo_size, cc26xx_bank->algo_code);
if (ERROR_OK != retval) {
LOG_ERROR("%s: Failed to load flash helper algorithm",
cc26xx_bank->family_name);
target_free_working_area(target, cc26xx_bank->working_area);
return retval;
}
/* Initialize the ARMv7 specific info to run the algorithm */
cc26xx_bank->armv7m_info.common_magic = ARMV7M_COMMON_MAGIC;
cc26xx_bank->armv7m_info.core_mode = ARM_MODE_THREAD;
/* Begin executing the flash helper algorithm */
retval = target_start_algorithm(target, 0, NULL, 0, NULL,
CC26XX_ALGO_BASE_ADDRESS, 0, &cc26xx_bank->armv7m_info);
if (ERROR_OK != retval) {
LOG_ERROR("%s: Failed to start flash helper algorithm",
cc26xx_bank->family_name);
target_free_working_area(target, cc26xx_bank->working_area);
return retval;
}
/*
* At this point, the algorithm is running on the target and
* ready to receive commands and data to flash the target
*/
return retval;
}
static int cc26xx_quit(struct flash_bank *bank)
{
struct target *target = bank->target;
struct cc26xx_bank *cc26xx_bank = bank->driver_priv;
int retval;
/* Regardless of the algo's status, attempt to halt the target */
(void)target_halt(target);
/* Now confirm target halted and clean up from flash helper algorithm */
retval = target_wait_algorithm(target, 0, NULL, 0, NULL, 0, FLASH_TIMEOUT,
&cc26xx_bank->armv7m_info);
target_free_working_area(target, cc26xx_bank->working_area);
cc26xx_bank->working_area = NULL;
return retval;
}
static int cc26xx_mass_erase(struct flash_bank *bank)
{
struct target *target = bank->target;
struct cc26xx_bank *cc26xx_bank = bank->driver_priv;
struct cc26xx_algo_params algo_params;
int retval;
if (TARGET_HALTED != target->state) {
LOG_ERROR("Target not halted");
return ERROR_TARGET_NOT_HALTED;
}
retval = cc26xx_init(bank);
if (ERROR_OK != retval)
return retval;
/* Initialize algorithm parameters */
buf_set_u32(algo_params.address, 0, 32, 0);
buf_set_u32(algo_params.length, 0, 32, 4);
buf_set_u32(algo_params.command, 0, 32, CC26XX_CMD_ERASE_ALL);
buf_set_u32(algo_params.status, 0, 32, CC26XX_BUFFER_FULL);
/* Issue flash helper algorithm parameters for mass erase */
retval = target_write_buffer(target, cc26xx_bank->params_addr[0],
sizeof(algo_params), (uint8_t *)&algo_params);
/* Wait for command to complete */
if (ERROR_OK == retval)
retval = cc26xx_wait_algo_done(bank, cc26xx_bank->params_addr[0]);
/* Regardless of errors, try to close down algo */
(void)cc26xx_quit(bank);
return retval;
}
FLASH_BANK_COMMAND_HANDLER(cc26xx_flash_bank_command)
{
struct cc26xx_bank *cc26xx_bank;
if (CMD_ARGC < 6)
return ERROR_COMMAND_SYNTAX_ERROR;
cc26xx_bank = malloc(sizeof(struct cc26xx_bank));
if (NULL == cc26xx_bank)
return ERROR_FAIL;
/* Initialize private flash information */
memset((void *)cc26xx_bank, 0x00, sizeof(struct cc26xx_bank));
cc26xx_bank->family_name = "cc26xx";
cc26xx_bank->device_type = CC26XX_NO_TYPE;
cc26xx_bank->sector_length = 0x1000;
/* Finish initialization of bank */
bank->driver_priv = cc26xx_bank;
bank->next = NULL;
return ERROR_OK;
}
static int cc26xx_erase(struct flash_bank *bank, int first, int last)
{
struct target *target = bank->target;
struct cc26xx_bank *cc26xx_bank = bank->driver_priv;
struct cc26xx_algo_params algo_params;
uint32_t address;
uint32_t length;
int retval;
if (TARGET_HALTED != target->state) {
LOG_ERROR("Target not halted");
return ERROR_TARGET_NOT_HALTED;
}
/* Do a mass erase if user requested all sectors of flash */
if ((first == 0) && (last == (bank->num_sectors - 1))) {
/* Request mass erase of flash */
return cc26xx_mass_erase(bank);
}
address = first * cc26xx_bank->sector_length;
length = (last - first + 1) * cc26xx_bank->sector_length;
retval = cc26xx_init(bank);
if (ERROR_OK != retval)
return retval;
/* Set up algorithm parameters for erase command */
buf_set_u32(algo_params.address, 0, 32, address);
buf_set_u32(algo_params.length, 0, 32, length);
buf_set_u32(algo_params.command, 0, 32, CC26XX_CMD_ERASE_SECTORS);
buf_set_u32(algo_params.status, 0, 32, CC26XX_BUFFER_FULL);
/* Issue flash helper algorithm parameters for erase */
retval = target_write_buffer(target, cc26xx_bank->params_addr[0],
sizeof(algo_params), (uint8_t *)&algo_params);
/* If no error, wait for erase to finish */
if (ERROR_OK == retval)
retval = cc26xx_wait_algo_done(bank, cc26xx_bank->params_addr[0]);
/* Regardless of errors, try to close down algo */
(void)cc26xx_quit(bank);
return retval;
}
static int cc26xx_protect(struct flash_bank *bank, int set, int first,
int last)
{
return ERROR_OK;
}
static int cc26xx_write(struct flash_bank *bank, const uint8_t *buffer,
uint32_t offset, uint32_t count)
{
struct target *target = bank->target;
struct cc26xx_bank *cc26xx_bank = bank->driver_priv;
struct cc26xx_algo_params algo_params[2];
uint32_t size = 0;
long long start_ms;
long long elapsed_ms;
uint32_t address;
uint32_t index;
int retval;
if (TARGET_HALTED != target->state) {
LOG_ERROR("Target not halted");
return ERROR_TARGET_NOT_HALTED;
}
retval = cc26xx_init(bank);
if (ERROR_OK != retval)
return retval;
/* Initialize algorithm parameters to default values */
buf_set_u32(algo_params[0].command, 0, 32, CC26XX_CMD_PROGRAM);
buf_set_u32(algo_params[1].command, 0, 32, CC26XX_CMD_PROGRAM);
/* Write requested data, ping-ponging between two buffers */
index = 0;
start_ms = timeval_ms();
address = bank->base + offset;
while (count > 0) {
if (count > cc26xx_bank->sector_length)
size = cc26xx_bank->sector_length;
else
size = count;
/* Put next block of data to flash into buffer */
retval = target_write_buffer(target, cc26xx_bank->buffer_addr[index],
size, buffer);
if (ERROR_OK != retval) {
LOG_ERROR("Unable to write data to target memory");
break;
}
/* Update algo parameters for next block */
buf_set_u32(algo_params[index].address, 0, 32, address);
buf_set_u32(algo_params[index].length, 0, 32, size);
buf_set_u32(algo_params[index].status, 0, 32, CC26XX_BUFFER_FULL);
/* Issue flash helper algorithm parameters for block write */
retval = target_write_buffer(target, cc26xx_bank->params_addr[index],
sizeof(algo_params[index]), (uint8_t *)&algo_params[index]);
if (ERROR_OK != retval)
break;
/* Wait for next ping pong buffer to be ready */
index ^= 1;
retval = cc26xx_wait_algo_done(bank, cc26xx_bank->params_addr[index]);
if (ERROR_OK != retval)
break;
count -= size;
buffer += size;
address += size;
elapsed_ms = timeval_ms() - start_ms;
if (elapsed_ms > 500)
keep_alive();
}
/* If no error yet, wait for last buffer to finish */
if (ERROR_OK == retval) {
index ^= 1;
retval = cc26xx_wait_algo_done(bank, cc26xx_bank->params_addr[index]);
}
/* Regardless of errors, try to close down algo */
(void)cc26xx_quit(bank);
return retval;
}
static int cc26xx_probe(struct flash_bank *bank)
{
struct target *target = bank->target;
struct cc26xx_bank *cc26xx_bank = bank->driver_priv;
uint32_t sector_length;
uint32_t value;
int num_sectors;
int max_sectors;
int retval;
retval = target_read_u32(target, FCFG1_ICEPICK_ID, &value);
if (ERROR_OK != retval)
return retval;
cc26xx_bank->icepick_id = value;
retval = target_read_u32(target, FCFG1_USER_ID, &value);
if (ERROR_OK != retval)
return retval;
cc26xx_bank->user_id = value;
cc26xx_bank->device_type = cc26xx_device_type(cc26xx_bank->icepick_id,
cc26xx_bank->user_id);
sector_length = cc26xx_sector_length(cc26xx_bank->icepick_id);
/* Set up appropriate flash helper algorithm */
switch (cc26xx_bank->icepick_id & ICEPICK_ID_MASK) {
case CC26X0_ICEPICK_ID:
case CC26X1_ICEPICK_ID:
case CC13X0_ICEPICK_ID:
/* Chameleon family device */
cc26xx_bank->algo_code = cc26x0_algo;
cc26xx_bank->algo_size = sizeof(cc26x0_algo);
cc26xx_bank->algo_working_size = CC26X0_WORKING_SIZE;
cc26xx_bank->buffer_addr[0] = CC26X0_ALGO_BUFFER_0;
cc26xx_bank->buffer_addr[1] = CC26X0_ALGO_BUFFER_1;
cc26xx_bank->params_addr[0] = CC26X0_ALGO_PARAMS_0;
cc26xx_bank->params_addr[1] = CC26X0_ALGO_PARAMS_1;
max_sectors = CC26X0_MAX_SECTORS;
break;
case CC13X2_CC26X2_ICEPICK_ID:
default:
/* Agama family device */
cc26xx_bank->algo_code = cc26x2_algo;
cc26xx_bank->algo_size = sizeof(cc26x2_algo);
cc26xx_bank->algo_working_size = CC26X2_WORKING_SIZE;
cc26xx_bank->buffer_addr[0] = CC26X2_ALGO_BUFFER_0;
cc26xx_bank->buffer_addr[1] = CC26X2_ALGO_BUFFER_1;
cc26xx_bank->params_addr[0] = CC26X2_ALGO_PARAMS_0;
cc26xx_bank->params_addr[1] = CC26X2_ALGO_PARAMS_1;
max_sectors = CC26X2_MAX_SECTORS;
break;
}
retval = target_read_u32(target, CC26XX_FLASH_SIZE_INFO, &value);
if (ERROR_OK != retval)
return retval;
num_sectors = value & 0xff;
if (num_sectors > max_sectors)
num_sectors = max_sectors;
bank->sectors = malloc(sizeof(struct flash_sector) * num_sectors);
if (NULL == bank->sectors)
return ERROR_FAIL;
bank->base = CC26XX_FLASH_BASE_ADDR;
bank->num_sectors = num_sectors;
bank->size = num_sectors * sector_length;
bank->write_start_alignment = 0;
bank->write_end_alignment = 0;
cc26xx_bank->sector_length = sector_length;
for (int i = 0; i < num_sectors; i++) {
bank->sectors[i].offset = i * sector_length;
bank->sectors[i].size = sector_length;
bank->sectors[i].is_erased = -1;
bank->sectors[i].is_protected = 0;
}
/* We've successfully determined the stats on the flash bank */
cc26xx_bank->probed = true;
/* If we fall through to here, then all went well */
return ERROR_OK;
}
static int cc26xx_auto_probe(struct flash_bank *bank)
{
struct cc26xx_bank *cc26xx_bank = bank->driver_priv;
int retval = ERROR_OK;
if (bank->bank_number != 0) {
/* Invalid bank number somehow */
return ERROR_FAIL;
}
if (!cc26xx_bank->probed)
retval = cc26xx_probe(bank);
return retval;
}
static int cc26xx_protect_check(struct flash_bank *bank)
{
return ERROR_OK;
}
static int cc26xx_info(struct flash_bank *bank, char *buf, int buf_size)
{
struct cc26xx_bank *cc26xx_bank = bank->driver_priv;
int printed = 0;
const char *device;
switch (cc26xx_bank->device_type) {
case CC26X0_TYPE:
device = "CC26x0";
break;
case CC26X1_TYPE:
device = "CC26x1";
break;
case CC13X0_TYPE:
device = "CC13x0";
break;
case CC13X2_TYPE:
device = "CC13x2";
break;
case CC26X2_TYPE:
device = "CC26x2";
break;
case CC26XX_NO_TYPE:
default:
device = "Unrecognized";
break;
}
printed = snprintf(buf, buf_size,
"%s device: ICEPick ID 0x%08x, USER ID 0x%08x\n",
device, cc26xx_bank->icepick_id, cc26xx_bank->user_id);
if (printed >= buf_size)
return ERROR_BUF_TOO_SMALL;
return ERROR_OK;
}
struct flash_driver cc26xx_flash = {
.name = "cc26xx",
.flash_bank_command = cc26xx_flash_bank_command,
.erase = cc26xx_erase,
.protect = cc26xx_protect,
.write = cc26xx_write,
.read = default_flash_read,
.probe = cc26xx_probe,
.auto_probe = cc26xx_auto_probe,
.erase_check = default_flash_blank_check,
.protect_check = cc26xx_protect_check,
.info = cc26xx_info,
.free_driver_priv = default_flash_free_driver_priv,
};

101
src/flash/nor/cc26xx.h Normal file
View File

@ -0,0 +1,101 @@
/***************************************************************************
* Copyright (C) 2017 by Texas Instruments, Inc. *
* *
* 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 2 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/>. *
***************************************************************************/
#ifndef OPENOCD_FLASH_NOR_CC26XX_H
#define OPENOCD_FLASH_NOR_CC26XX_H
/* Addresses of FCFG1 registers to access ICEPick Device ID and User ID */
#define FCFG1_ICEPICK_ID 0x50001318
#define FCFG1_USER_ID 0x50001294
/* ICEPick device ID mask and values */
#define ICEPICK_ID_MASK 0x0fffffff
#define ICEPICK_REV_MASK 0xf0000000
#define CC26X0_ICEPICK_ID 0x0b99a02f
#define CC26X1_ICEPICK_ID 0x0b9bd02f
#define CC13X0_ICEPICK_ID 0x0b9be02f
#define CC13X2_CC26X2_ICEPICK_ID 0x0bb4102f
/* User ID mask for Agama CC13x2 vs CC26x2 */
#define USER_ID_CC13_MASK 0x00800000
/* Common CC26xx/CC13xx flash and memory parameters */
#define CC26XX_FLASH_BASE_ADDR 0x00000000
#define CC26XX_FLASH_SIZE_INFO 0x4003002c
#define CC26XX_SRAM_SIZE_INFO 0x40082250
#define CC26XX_ALGO_BASE_ADDRESS 0x20000000
/* Chameleon CC26x0/CC13x0 specific parameters */
#define CC26X0_MAX_SECTORS 32
#define CC26X0_SECTOR_LENGTH 0x1000
#define CC26X0_ALGO_BUFFER_0 0x20001c00
#define CC26X0_ALGO_BUFFER_1 0x20002c00
#define CC26X0_ALGO_PARAMS_0 0x20001bd8
#define CC26X0_ALGO_PARAMS_1 0x20001bec
#define CC26X0_WORKING_SIZE (CC26X0_ALGO_BUFFER_1 + CC26X0_SECTOR_LENGTH - \
CC26XX_ALGO_BASE_ADDRESS)
/* Agama CC26x2/CC13x2 specific parameters */
#define CC26X2_MAX_SECTORS 128
#define CC26X2_SECTOR_LENGTH 0x2000
#define CC26X2_ALGO_BUFFER_0 0x20002000
#define CC26X2_ALGO_BUFFER_1 0x20004000
#define CC26X2_ALGO_PARAMS_0 0x20001fd8
#define CC26X2_ALGO_PARAMS_1 0x20001fec
#define CC26X2_WORKING_SIZE (CC26X2_ALGO_BUFFER_1 + CC26X2_SECTOR_LENGTH - \
CC26XX_ALGO_BASE_ADDRESS)
/* CC26xx flash helper algorithm buffer flags */
#define CC26XX_BUFFER_EMPTY 0x00000000
#define CC26XX_BUFFER_FULL 0xffffffff
/* CC26XX flash helper algorithm commands */
#define CC26XX_CMD_NO_ACTION 0
#define CC26XX_CMD_ERASE_ALL 1
#define CC26XX_CMD_PROGRAM 2
#define CC26XX_CMD_ERASE_AND_PROGRAM 3
#define CC26XX_CMD_ERASE_AND_PROGRAM_WITH_RETAIN 4
#define CC26XX_CMD_ERASE_SECTORS 5
/* CC26xx and CC13xx device types */
#define CC26XX_NO_TYPE 0 /* Device type not determined yet */
#define CC26X0_TYPE 1 /* CC26x0 Chameleon device */
#define CC26X1_TYPE 2 /* CC26x1 Chameleon device */
#define CC26X2_TYPE 3 /* CC26x2 Agama device */
#define CC13X0_TYPE 4 /* CC13x0 Chameleon device */
#define CC13X2_TYPE 5 /* CC13x2 Agama device */
/* Flash helper algorithm parameter block struct */
#define CC26XX_STATUS_OFFSET 0x0c
struct cc26xx_algo_params {
uint8_t address[4];
uint8_t length[4];
uint8_t command[4];
uint8_t status[4];
};
/* Flash helper algorithm for CC26x0 Chameleon targets */
const uint8_t cc26x0_algo[] = {
#include "../../../contrib/loaders/flash/cc26xx/cc26x0_algo.inc"
};
/* Flash helper algorithm for CC26x2 Agama targets */
const uint8_t cc26x2_algo[] = {
#include "../../../contrib/loaders/flash/cc26xx/cc26x2_algo.inc"
};
#endif /* OPENOCD_FLASH_NOR_CC26XX_H */

529
src/flash/nor/cc3220sf.c Normal file
View File

@ -0,0 +1,529 @@
/***************************************************************************
* Copyright (C) 2017 by Texas Instruments, Inc. *
* *
* 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 2 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/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "imp.h"
#include "cc3220sf.h"
#include <helper/time_support.h>
#include <target/algorithm.h>
#include <target/armv7m.h>
#define FLASH_TIMEOUT 5000
struct cc3220sf_bank {
bool probed;
struct armv7m_algorithm armv7m_info;
};
static int cc3220sf_mass_erase(struct flash_bank *bank)
{
struct target *target = bank->target;
bool done;
long long start_ms;
long long elapsed_ms;
uint32_t value;
int retval = ERROR_OK;
if (TARGET_HALTED != target->state) {
LOG_ERROR("Target not halted");
return ERROR_TARGET_NOT_HALTED;
}
/* Set starting address to erase to zero */
retval = target_write_u32(target, FMA_REGISTER_ADDR, 0);
if (ERROR_OK != retval)
return retval;
/* Write the MERASE bit of the FMC register */
retval = target_write_u32(target, FMC_REGISTER_ADDR, FMC_MERASE_VALUE);
if (ERROR_OK != retval)
return retval;
/* Poll the MERASE bit until the mass erase is complete */
done = false;
start_ms = timeval_ms();
while (!done) {
retval = target_read_u32(target, FMC_REGISTER_ADDR, &value);
if (ERROR_OK != retval)
return retval;
if ((value & FMC_MERASE_BIT) == 0) {
/* Bit clears when mass erase is finished */
done = true;
} else {
elapsed_ms = timeval_ms() - start_ms;
if (elapsed_ms > 500)
keep_alive();
if (elapsed_ms > FLASH_TIMEOUT)
break;
}
}
if (!done) {
/* Mass erase timed out waiting for confirmation */
return ERROR_FAIL;
}
return retval;
}
FLASH_BANK_COMMAND_HANDLER(cc3220sf_flash_bank_command)
{
struct cc3220sf_bank *cc3220sf_bank;
if (CMD_ARGC < 6)
return ERROR_COMMAND_SYNTAX_ERROR;
cc3220sf_bank = malloc(sizeof(struct cc3220sf_bank));
if (NULL == cc3220sf_bank)
return ERROR_FAIL;
/* Initialize private flash information */
cc3220sf_bank->probed = false;
/* Finish initialization of flash bank */
bank->driver_priv = cc3220sf_bank;
bank->next = NULL;
return ERROR_OK;
}
static int cc3220sf_erase(struct flash_bank *bank, int first, int last)
{
struct target *target = bank->target;
bool done;
long long start_ms;
long long elapsed_ms;
uint32_t address;
uint32_t value;
int retval = ERROR_OK;
if (TARGET_HALTED != target->state) {
LOG_ERROR("Target not halted");
return ERROR_TARGET_NOT_HALTED;
}
/* Do a mass erase if user requested all sectors of flash */
if ((first == 0) && (last == (bank->num_sectors - 1))) {
/* Request mass erase of flash */
return cc3220sf_mass_erase(bank);
}
/* Erase requested sectors one by one */
for (int i = first; i <= last; i++) {
/* Determine address of sector to erase */
address = FLASH_BASE_ADDR + i * FLASH_SECTOR_SIZE;
/* Set starting address to erase */
retval = target_write_u32(target, FMA_REGISTER_ADDR, address);
if (ERROR_OK != retval)
return retval;
/* Write the ERASE bit of the FMC register */
retval = target_write_u32(target, FMC_REGISTER_ADDR, FMC_ERASE_VALUE);
if (ERROR_OK != retval)
return retval;
/* Poll the ERASE bit until the erase is complete */
done = false;
start_ms = timeval_ms();
while (!done) {
retval = target_read_u32(target, FMC_REGISTER_ADDR, &value);
if (ERROR_OK != retval)
return retval;
if ((value & FMC_ERASE_BIT) == 0) {
/* Bit clears when mass erase is finished */
done = true;
} else {
elapsed_ms = timeval_ms() - start_ms;
if (elapsed_ms > 500)
keep_alive();
if (elapsed_ms > FLASH_TIMEOUT)
break;
}
}
if (!done) {
/* Sector erase timed out waiting for confirmation */
return ERROR_FAIL;
}
}
return retval;
}
static int cc3220sf_protect(struct flash_bank *bank, int set, int first,
int last)
{
return ERROR_OK;
}
static int cc3220sf_write(struct flash_bank *bank, const uint8_t *buffer,
uint32_t offset, uint32_t count)
{
struct target *target = bank->target;
struct cc3220sf_bank *cc3220sf_bank = bank->driver_priv;
struct working_area *algo_working_area;
struct working_area *buffer_working_area;
struct reg_param reg_params[3];
uint32_t algo_base_address;
uint32_t algo_buffer_address;
uint32_t algo_buffer_size;
uint32_t address;
uint32_t remaining;
uint32_t words;
uint32_t result;
int retval = ERROR_OK;
if (TARGET_HALTED != target->state) {
LOG_ERROR("Target not halted");
return ERROR_TARGET_NOT_HALTED;
}
/* Obtain working area to use for flash helper algorithm */
retval = target_alloc_working_area(target, sizeof(cc3220sf_algo),
&algo_working_area);
if (ERROR_OK != retval)
return retval;
/* Obtain working area to use for flash buffer */
retval = target_alloc_working_area(target,
target_get_working_area_avail(target), &buffer_working_area);
if (ERROR_OK != retval) {
target_free_working_area(target, algo_working_area);
return retval;
}
algo_base_address = algo_working_area->address;
algo_buffer_address = buffer_working_area->address;
algo_buffer_size = buffer_working_area->size;
/* Make sure buffer size is a multiple of 32 word (0x80 byte) chunks */
/* (algo runs more efficiently if it operates on 32 words at a time) */
if (algo_buffer_size > 0x80)
algo_buffer_size &= ~0x7f;
/* Write flash helper algorithm into target memory */
retval = target_write_buffer(target, algo_base_address,
sizeof(cc3220sf_algo), cc3220sf_algo);
if (ERROR_OK != retval) {
target_free_working_area(target, algo_working_area);
target_free_working_area(target, buffer_working_area);
return retval;
}
/* Initialize the ARMv7m specific info to run the algorithm */
cc3220sf_bank->armv7m_info.common_magic = ARMV7M_COMMON_MAGIC;
cc3220sf_bank->armv7m_info.core_mode = ARM_MODE_THREAD;
/* Initialize register params for flash helper algorithm */
init_reg_param(&reg_params[0], "r0", 32, PARAM_OUT);
init_reg_param(&reg_params[1], "r1", 32, PARAM_OUT);
init_reg_param(&reg_params[2], "r2", 32, PARAM_IN_OUT);
/* Prepare to write to flash */
address = FLASH_BASE_ADDR + offset;
remaining = count;
/* The flash hardware can only write complete words to flash. If
* an unaligned address is passed in, we must do a read-modify-write
* on a word with enough bytes to align the rest of the buffer. And
* if less than a whole word remains at the end, we must also do a
* read-modify-write on a final word to finish up.
*/
/* Do one word write to align address on 32-bit boundary if needed */
if (0 != (address & 0x3)) {
uint8_t head[4];
/* Get starting offset for data to write (will be 1 to 3) */
uint32_t head_offset = address & 0x03;
/* Get the aligned address to write this first word to */
uint32_t head_address = address & 0xfffffffc;
/* Retrieve what is already in flash at the head address */
retval = target_read_buffer(target, head_address, sizeof(head), head);
if (ERROR_OK == retval) {
/* Substitute in the new data to write */
while ((remaining > 0) && (head_offset < 4)) {
head[head_offset] = *buffer;
head_offset++;
address++;
buffer++;
remaining--;
}
}
if (ERROR_OK == retval) {
/* Helper parameters are passed in registers R0-R2 */
/* Set start of data buffer, address to write to, and word count */
buf_set_u32(reg_params[0].value, 0, 32, algo_buffer_address);
buf_set_u32(reg_params[1].value, 0, 32, head_address);
buf_set_u32(reg_params[2].value, 0, 32, 1);
/* Write head value into buffer to flash */
retval = target_write_buffer(target, algo_buffer_address,
sizeof(head), head);
}
if (ERROR_OK == retval) {
/* Execute the flash helper algorithm */
retval = target_run_algorithm(target, 0, NULL, 3, reg_params,
algo_base_address, 0, FLASH_TIMEOUT,
&cc3220sf_bank->armv7m_info);
if (ERROR_OK != retval)
LOG_ERROR("cc3220sf: Flash algorithm failed to run");
/* Check that the head value was written to flash */
result = buf_get_u32(reg_params[2].value, 0, 32);
if (0 != result) {
retval = ERROR_FAIL;
LOG_ERROR("cc3220sf: Flash operation failed");
}
}
}
/* Check if there's data at end of buffer that isn't a full word */
uint32_t tail_count = remaining & 0x03;
/* Adjust remaining so it is a multiple of whole words */
remaining -= tail_count;
while ((ERROR_OK == retval) && (remaining > 0)) {
/* Set start of data buffer and address to write to */
buf_set_u32(reg_params[0].value, 0, 32, algo_buffer_address);
buf_set_u32(reg_params[1].value, 0, 32, address);
/* Download data to write into memory buffer */
if (remaining >= algo_buffer_size) {
/* Fill up buffer with data to flash */
retval = target_write_buffer(target, algo_buffer_address,
algo_buffer_size, buffer);
if (ERROR_OK != retval)
break;
/* Count to write is in 32-bit words */
words = algo_buffer_size / 4;
/* Bump variables to next data */
address += algo_buffer_size;
buffer += algo_buffer_size;
remaining -= algo_buffer_size;
} else {
/* Fill buffer with what's left of the data */
retval = target_write_buffer(target, algo_buffer_address,
remaining, buffer);
if (ERROR_OK != retval)
break;
/* Calculate the final word count to write */
words = remaining / 4;
if (0 != (remaining % 4))
words++;
/* Bump variables to any final data */
address += remaining;
buffer += remaining;
remaining = 0;
}
/* Set number of words to write */
buf_set_u32(reg_params[2].value, 0, 32, words);
/* Execute the flash helper algorithm */
retval = target_run_algorithm(target, 0, NULL, 3, reg_params,
algo_base_address, 0, FLASH_TIMEOUT,
&cc3220sf_bank->armv7m_info);
if (ERROR_OK != retval) {
LOG_ERROR("cc3220sf: Flash algorithm failed to run");
break;
}
/* Check that all words were written to flash */
result = buf_get_u32(reg_params[2].value, 0, 32);
if (0 != result) {
retval = ERROR_FAIL;
LOG_ERROR("cc3220sf: Flash operation failed");
break;
}
}
/* Do one word write for any final bytes less than a full word */
if ((ERROR_OK == retval) && (0 != tail_count)) {
uint8_t tail[4];
/* Set starting byte offset for data to write */
uint32_t tail_offset = 0;
/* Retrieve what is already in flash at the tail address */
retval = target_read_buffer(target, address, sizeof(tail), tail);
if (ERROR_OK == retval) {
/* Substitute in the new data to write */
while (tail_count > 0) {
tail[tail_offset] = *buffer;
tail_offset++;
buffer++;
tail_count--;
}
}
if (ERROR_OK == retval) {
/* Set start of data buffer, address to write to, and word count */
buf_set_u32(reg_params[0].value, 0, 32, algo_buffer_address);
buf_set_u32(reg_params[1].value, 0, 32, address);
buf_set_u32(reg_params[2].value, 0, 32, 1);
/* Write tail value into buffer to flash */
retval = target_write_buffer(target, algo_buffer_address,
sizeof(tail), tail);
}
if (ERROR_OK == retval) {
/* Execute the flash helper algorithm */
retval = target_run_algorithm(target, 0, NULL, 3, reg_params,
algo_base_address, 0, FLASH_TIMEOUT,
&cc3220sf_bank->armv7m_info);
if (ERROR_OK != retval)
LOG_ERROR("cc3220sf: Flash algorithm failed to run");
/* Check that the tail was written to flash */
result = buf_get_u32(reg_params[2].value, 0, 32);
if (0 != result) {
retval = ERROR_FAIL;
LOG_ERROR("cc3220sf: Flash operation failed");
}
}
}
/* Free resources */
destroy_reg_param(&reg_params[0]);
destroy_reg_param(&reg_params[1]);
destroy_reg_param(&reg_params[2]);
target_free_working_area(target, algo_working_area);
target_free_working_area(target, buffer_working_area);
return retval;
}
static int cc3220sf_probe(struct flash_bank *bank)
{
struct cc3220sf_bank *cc3220sf_bank = bank->driver_priv;
uint32_t base;
uint32_t size;
int num_sectors;
int bank_id;
bank_id = bank->bank_number;
if (0 == bank_id) {
base = FLASH_BASE_ADDR;
size = FLASH_NUM_SECTORS * FLASH_SECTOR_SIZE;
num_sectors = FLASH_NUM_SECTORS;
} else {
/* Invalid bank number somehow */
return ERROR_FAIL;
}
if (NULL != bank->sectors) {
free(bank->sectors);
bank->sectors = NULL;
}
bank->sectors = malloc(sizeof(struct flash_sector) * num_sectors);
if (NULL == bank->sectors)
return ERROR_FAIL;
bank->base = base;
bank->size = size;
bank->write_start_alignment = 0;
bank->write_end_alignment = 0;
bank->num_sectors = num_sectors;
for (int i = 0; i < num_sectors; i++) {
bank->sectors[i].offset = i * FLASH_SECTOR_SIZE;
bank->sectors[i].size = FLASH_SECTOR_SIZE;
bank->sectors[i].is_erased = -1;
bank->sectors[i].is_protected = 0;
}
/* We've successfully recorded the stats on this flash bank */
cc3220sf_bank->probed = true;
/* If we fall through to here, then all went well */
return ERROR_OK;
}
static int cc3220sf_auto_probe(struct flash_bank *bank)
{
struct cc3220sf_bank *cc3220sf_bank = bank->driver_priv;
int retval = ERROR_OK;
if (0 != bank->bank_number) {
/* Invalid bank number somehow */
return ERROR_FAIL;
}
if (!cc3220sf_bank->probed)
retval = cc3220sf_probe(bank);
return retval;
}
static int cc3220sf_protect_check(struct flash_bank *bank)
{
return ERROR_OK;
}
static int cc3220sf_info(struct flash_bank *bank, char *buf, int buf_size)
{
int printed;
printed = snprintf(buf, buf_size, "CC3220SF with 1MB internal flash\n");
if (printed >= buf_size)
return ERROR_BUF_TOO_SMALL;
return ERROR_OK;
}
struct flash_driver cc3220sf_flash = {
.name = "cc3220sf",
.flash_bank_command = cc3220sf_flash_bank_command,
.erase = cc3220sf_erase,
.protect = cc3220sf_protect,
.write = cc3220sf_write,
.read = default_flash_read,
.probe = cc3220sf_probe,
.auto_probe = cc3220sf_auto_probe,
.erase_check = default_flash_blank_check,
.protect_check = cc3220sf_protect_check,
.info = cc3220sf_info,
.free_driver_priv = default_flash_free_driver_priv,
};

45
src/flash/nor/cc3220sf.h Normal file
View File

@ -0,0 +1,45 @@
/***************************************************************************
* Copyright (C) 2017 by Texas Instruments, Inc. *
* *
* 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 2 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/>. *
***************************************************************************/
#ifndef OPENOCD_FLASH_NOR_CC3220SF_H
#define OPENOCD_FLASH_NOR_CC3220SF_H
/* CC3220SF device types */
#define CC3220_NO_TYPE 0 /* Device type not determined yet */
#define CC3220_OTHER 1 /* CC3220 variant without flash */
#define CC3220SF 2 /* CC3220SF variant with flash */
/* Flash parameters */
#define FLASH_BASE_ADDR 0x01000000
#define FLASH_SECTOR_SIZE 2048
#define FLASH_NUM_SECTORS 512
/* CC2200SF flash registers */
#define FMA_REGISTER_ADDR 0x400FD000
#define FMC_REGISTER_ADDR 0x400FD008
#define FMC_DEFAULT_VALUE 0xA4420000
#define FMC_ERASE_BIT 0x00000002
#define FMC_MERASE_BIT 0x00000004
#define FMC_ERASE_VALUE (FMC_DEFAULT_VALUE | FMC_ERASE_BIT)
#define FMC_MERASE_VALUE (FMC_DEFAULT_VALUE | FMC_MERASE_BIT)
/* Flash helper algorithm for CC3220SF */
const uint8_t cc3220sf_algo[] = {
#include "../../../contrib/loaders/flash/cc3220sf/cc3220sf.inc"
};
#endif /* OPENOCD_FLASH_NOR_CC3220SF_H */

View File

@ -188,9 +188,17 @@ void flash_free_all_banks(void)
else
LOG_WARNING("Flash driver of %s does not support free_driver_priv()", bank->name);
free(bank->name);
/* For 'virtual' flash driver bank->sectors and bank->prot_blocks pointers are copied from
* master flash_bank structure. They point to memory locations allocated by master flash driver
* so master driver is responsible for releasing them.
* Avoid UB caused by double-free memory corruption if flash bank is 'virtual'. */
if (strcmp(bank->driver->name, "virtual") != 0) {
free(bank->sectors);
free(bank->prot_blocks);
}
free(bank->name);
free(bank);
bank = next;
}

View File

@ -32,6 +32,8 @@ extern struct flash_driver ath79_flash;
extern struct flash_driver atsamv_flash;
extern struct flash_driver avr_flash;
extern struct flash_driver bluenrgx_flash;
extern struct flash_driver cc3220sf_flash;
extern struct flash_driver cc26xx_flash;
extern struct flash_driver cfi_flash;
extern struct flash_driver dsp5680xx_flash;
extern struct flash_driver efm32_flash;
@ -49,6 +51,7 @@ extern struct flash_driver lpc2900_flash;
extern struct flash_driver lpcspifi_flash;
extern struct flash_driver mdr_flash;
extern struct flash_driver mrvlqspi_flash;
extern struct flash_driver msp432_flash;
extern struct flash_driver niietcm4_flash;
extern struct flash_driver nrf5_flash;
extern struct flash_driver nrf51_flash;
@ -56,6 +59,9 @@ extern struct flash_driver numicro_flash;
extern struct flash_driver ocl_flash;
extern struct flash_driver pic32mx_flash;
extern struct flash_driver psoc4_flash;
extern struct flash_driver psoc5lp_flash;
extern struct flash_driver psoc5lp_eeprom_flash;
extern struct flash_driver psoc5lp_nvl_flash;
extern struct flash_driver psoc6_flash;
extern struct flash_driver sim3x_flash;
extern struct flash_driver stellaris_flash;
@ -91,6 +97,8 @@ static struct flash_driver *flash_drivers[] = {
&atsamv_flash,
&avr_flash,
&bluenrgx_flash,
&cc3220sf_flash,
&cc26xx_flash,
&cfi_flash,
&dsp5680xx_flash,
&efm32_flash,
@ -108,6 +116,7 @@ static struct flash_driver *flash_drivers[] = {
&lpcspifi_flash,
&mdr_flash,
&mrvlqspi_flash,
&msp432_flash,
&niietcm4_flash,
&nrf5_flash,
&nrf51_flash,
@ -115,6 +124,9 @@ static struct flash_driver *flash_drivers[] = {
&ocl_flash,
&pic32mx_flash,
&psoc4_flash,
&psoc5lp_flash,
&psoc5lp_eeprom_flash,
&psoc5lp_nvl_flash,
&psoc6_flash,
&sim3x_flash,
&stellaris_flash,

View File

@ -1179,5 +1179,6 @@ struct flash_driver fespi_flash = {
.auto_probe = fespi_auto_probe,
.erase_check = default_flash_blank_check,
.protect_check = fespi_protect_check,
.info = get_fespi_info
.info = get_fespi_info,
.free_driver_priv = default_flash_free_driver_priv
};

View File

@ -937,7 +937,7 @@ static int kinetis_create_missing_banks(struct kinetis_chip *k_chip)
unsigned num_blocks;
struct kinetis_flash_bank *k_bank;
struct flash_bank *bank;
char base_name[80], name[80], num[4];
char base_name[69], name[80], num[4];
char *class, *p;
num_blocks = k_chip->num_pflash_blocks + k_chip->num_nvm_blocks;
@ -948,7 +948,8 @@ static int kinetis_create_missing_banks(struct kinetis_chip *k_chip)
bank = k_chip->banks[0].bank;
if (bank && bank->name) {
strncpy(base_name, bank->name, sizeof(base_name));
strncpy(base_name, bank->name, sizeof(base_name) - 1);
base_name[sizeof(base_name) - 1] = '\0';
p = strstr(base_name, ".pflash");
if (p) {
*p = '\0';
@ -960,7 +961,8 @@ static int kinetis_create_missing_banks(struct kinetis_chip *k_chip)
}
}
} else {
strncpy(base_name, target_name(k_chip->target), sizeof(base_name));
strncpy(base_name, target_name(k_chip->target), sizeof(base_name) - 1);
base_name[sizeof(base_name) - 1] = '\0';
p = strstr(base_name, ".cpu");
if (p)
*p = '\0';
@ -2012,7 +2014,7 @@ static int kinetis_probe_chip(struct kinetis_chip *k_chip)
unsigned cpu_mhz = 120;
unsigned idx;
bool use_nvm_marking = false;
char flash_marking[11], nvm_marking[2];
char flash_marking[12], nvm_marking[2];
char name[40];
k_chip->probed = false;

1103
src/flash/nor/msp432.c Normal file

File diff suppressed because it is too large Load Diff

127
src/flash/nor/msp432.h Normal file
View File

@ -0,0 +1,127 @@
/***************************************************************************
* Copyright (C) 2018 by Texas Instruments, Inc. *
* *
* 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 2 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/>. *
***************************************************************************/
#ifndef OPENOCD_FLASH_NOR_MSP432_H
#define OPENOCD_FLASH_NOR_MSP432_H
/* MSP432 family types */
#define MSP432_NO_FAMILY 0 /* Family type not determined yet */
#define MSP432E4 1 /* MSP432E4 family of devices */
#define MSP432P4 2 /* MSP432P4 family of devices */
/* MSP432 device types */
#define MSP432_NO_TYPE 0 /* Device type not determined yet */
#define MSP432P401X_DEPR 1 /* Early MSP432P401x offerings, now deprecated */
#define MSP432P401X 2 /* MSP432P401x device, revision C or higher */
#define MSP432P411X 3 /* MSP432P411x device, revision A or higher */
#define MSP432P401X_GUESS 4 /* Assuming it's an MSP432P401x device */
#define MSP432P411X_GUESS 5 /* Assuming it's an MSP432P411x device */
#define MSP432E401Y 6 /* MSP432E401Y device */
#define MSP432E411Y 7 /* MSP432E401Y device */
#define MSP432E4X_GUESS 8 /* Assuming it's an MSP432E4x device */
/* MSP432P4 flash parameters */
#define P4_FLASH_MAIN_BASE 0x00000000
#define P4_FLASH_INFO_BASE 0x00200000
#define P4_SECTOR_LENGTH 0x1000
#define P4_ALGO_ENTRY_ADDR 0x01000110
/* MSP432E4 flash paramters */
#define E4_FLASH_BASE 0x00000000
#define E4_FLASH_SIZE 0x100000
#define E4_SECTOR_LENGTH 0x4000
#define E4_ALGO_ENTRY_ADDR 0x20000110
/* Flash helper algorithm key addresses */
#define ALGO_BASE_ADDR 0x20000000
#define ALGO_BUFFER1_ADDR 0x20002000
#define ALGO_BUFFER2_ADDR 0x20003000
#define ALGO_PARAMS_BASE_ADDR 0x20000150
#define ALGO_FLASH_COMMAND_ADDR 0x20000150
#define ALGO_RETURN_CODE_ADDR 0x20000154
#define ALGO_FLASH_DEST_ADDR 0x2000015c
#define ALGO_FLASH_LENGTH_ADDR 0x20000160
#define ALGO_BUFFER1_STATUS_ADDR 0x20000164
#define ALGO_BUFFER2_STATUS_ADDR 0x20000168
#define ALGO_ERASE_PARAM_ADDR 0x2000016c
#define ALGO_UNLOCK_BSL_ADDR 0x20000170
#define ALGO_STACK_POINTER_ADDR 0x20002000
/* Flash helper algorithm key sizes */
#define ALGO_BUFFER_SIZE 0x1000
#define ALGO_WORKING_SIZE (ALGO_BUFFER2_ADDR + 0x1000 - ALGO_BASE_ADDR)
/* Flash helper algorithm flash commands */
#define FLASH_NO_COMMAND 0
#define FLASH_MASS_ERASE 1
#define FLASH_SECTOR_ERASE 2
#define FLASH_PROGRAM 4
#define FLASH_INIT 8
#define FLASH_EXIT 16
#define FLASH_CONTINUOUS 32
/* Flash helper algorithm return codes */
#define FLASH_BUSY 0x00000001
#define FLASH_SUCCESS 0x00000ACE
#define FLASH_ERROR 0x0000DEAD
#define FLASH_TIMEOUT_ERROR 0xDEAD0000
#define FLASH_VERIFY_ERROR 0xDEADDEAD
#define FLASH_WRONG_COMMAND 0x00000BAD
#define FLASH_POWER_ERROR 0x00DEAD00
/* Flash helper algorithm buffer status values */
#define BUFFER_INACTIVE 0x00
#define BUFFER_ACTIVE 0x01
#define BUFFER_DATA_READY 0x10
/* Flash helper algorithm erase parameters */
#define FLASH_ERASE_MAIN 0x01
#define FLASH_ERASE_INFO 0x02
/* Flash helper algorithm lock/unlock BSL options */
#define FLASH_LOCK_BSL 0x00
#define FLASH_UNLOCK_BSL 0x0b
/* Flash helper algorithm parameter block struct */
struct msp432_algo_params {
uint8_t flash_command[4];
uint8_t return_code[4];
uint8_t _reserved0[4];
uint8_t address[4];
uint8_t length[4];
uint8_t buffer1_status[4];
uint8_t buffer2_status[4];
uint8_t erase_param[4];
uint8_t unlock_bsl[4];
};
/* Flash helper algorithm for MSP432P401x targets */
const uint8_t msp432p401x_algo[] = {
#include "../../../contrib/loaders/flash/msp432/msp432p401x_algo.inc"
};
/* Flash helper algorithm for MSP432P411x targets */
const uint8_t msp432p411x_algo[] = {
#include "../../../contrib/loaders/flash/msp432/msp432p411x_algo.inc"
};
/* Flash helper algorithm for MSP432E4x targets */
const uint8_t msp432e4x_algo[] = {
#include "../../../contrib/loaders/flash/msp432/msp432e4x_algo.inc"
};
#endif /* OPENOCD_FLASH_NOR_MSP432_H */

View File

@ -108,6 +108,7 @@ enum nrf5_nvmc_config_bits {
struct nrf5_info {
uint32_t code_page_size;
uint32_t refcount;
struct {
bool probed;
@ -204,6 +205,7 @@ static const struct nrf5_device_spec nrf5_known_devices_table[] = {
/* nRF52832 Devices */
NRF5_DEVICE_DEF(0x00C7, "52832", "QFAA", "B0", 512),
NRF5_DEVICE_DEF(0x0139, "52832", "QFAA", "E0", 512),
};
static int nrf5_bank_is_probed(struct flash_bank *bank)
@ -531,7 +533,6 @@ static int nrf5_probe(struct flash_bank *bank)
bank->sectors[0].size = bank->size;
bank->sectors[0].offset = 0;
/* mark as unknown */
bank->sectors[0].is_erased = 0;
bank->sectors[0].is_protected = 0;
@ -553,17 +554,6 @@ static int nrf5_auto_probe(struct flash_bank *bank)
return nrf5_probe(bank);
}
static struct flash_sector *nrf5_find_sector_by_address(struct flash_bank *bank, uint32_t address)
{
struct nrf5_info *chip = bank->driver_priv;
for (int i = 0; i < bank->num_sectors; i++)
if (bank->sectors[i].offset <= address &&
address < (bank->sectors[i].offset + chip->code_page_size))
return &bank->sectors[i];
return NULL;
}
static int nrf5_erase_all(struct nrf5_info *chip)
{
LOG_DEBUG("Erasing all non-volatile memory");
@ -615,9 +605,6 @@ static int nrf5_erase_page(struct flash_bank *bank,
sector->offset);
}
if (res == ERROR_OK)
sector->is_erased = 1;
return res;
}
@ -743,48 +730,22 @@ static int nrf5_write_pages(struct flash_bank *bank, uint32_t start, uint32_t en
{
int res = ERROR_FAIL;
struct nrf5_info *chip = bank->driver_priv;
struct flash_sector *sector;
uint32_t offset;
assert(start % chip->code_page_size == 0);
assert(end % chip->code_page_size == 0);
/* Erase all sectors */
for (offset = start; offset < end; offset += chip->code_page_size) {
sector = nrf5_find_sector_by_address(bank, offset);
if (!sector) {
LOG_ERROR("Invalid sector @ 0x%08"PRIx32, offset);
return ERROR_FLASH_SECTOR_INVALID;
}
if (sector->is_protected) {
LOG_ERROR("Can't erase protected sector @ 0x%08"PRIx32, offset);
goto error;
}
if (sector->is_erased != 1) { /* 1 = erased, 0= not erased, -1 = unknown */
res = nrf5_erase_page(bank, chip, sector);
if (res != ERROR_OK) {
LOG_ERROR("Failed to erase sector @ 0x%08"PRIx32, sector->offset);
goto error;
}
}
sector->is_erased = 0;
}
res = nrf5_nvmc_write_enable(chip);
if (res != ERROR_OK)
goto error;
res = nrf5_ll_flash_write(chip, start, buffer, (end - start));
if (res != ERROR_OK)
goto set_read_only;
goto error;
return nrf5_nvmc_read_only(chip);
set_read_only:
nrf5_nvmc_read_only(chip);
error:
nrf5_nvmc_read_only(chip);
LOG_ERROR("Failed to write to nrf5 flash");
return res;
}
@ -876,11 +837,9 @@ static int nrf5_uicr_flash_write(struct flash_bank *bank,
if (res != ERROR_OK)
return res;
if (sector->is_erased != 1) {
res = nrf5_erase_page(bank, chip, sector);
if (res != ERROR_OK)
return res;
}
res = nrf5_nvmc_write_enable(chip);
if (res != ERROR_OK)
@ -911,6 +870,18 @@ static int nrf5_write(struct flash_bank *bank, const uint8_t *buffer,
return chip->bank[bank->bank_number].write(bank, chip, buffer, offset, count);
}
static void nrf5_free_driver_priv(struct flash_bank *bank)
{
struct nrf5_info *chip = bank->driver_priv;
if (chip == NULL)
return;
chip->refcount--;
if (chip->refcount == 0) {
free(chip);
bank->driver_priv = NULL;
}
}
FLASH_BANK_COMMAND_HANDLER(nrf5_flash_bank_command)
{
@ -946,6 +917,7 @@ FLASH_BANK_COMMAND_HANDLER(nrf5_flash_bank_command)
break;
}
chip->refcount++;
chip->bank[bank->bank_number].probed = false;
bank->driver_priv = chip;
@ -992,9 +964,6 @@ COMMAND_HANDLER(nrf5_handle_mass_erase_command)
return res;
}
for (int i = 0; i < bank->num_sectors; i++)
bank->sectors[i].is_erased = 1;
res = nrf5_protect_check(bank);
if (res != ERROR_OK) {
LOG_ERROR("Failed to check chip's write protection");
@ -1005,8 +974,6 @@ COMMAND_HANDLER(nrf5_handle_mass_erase_command)
if (res != ERROR_OK)
return res;
bank->sectors[0].is_erased = 1;
return ERROR_OK;
}
@ -1175,6 +1142,7 @@ struct flash_driver nrf5_flash = {
.auto_probe = nrf5_auto_probe,
.erase_check = default_flash_blank_check,
.protect_check = nrf5_protect_check,
.free_driver_priv = nrf5_free_driver_priv,
};
/* We need to retain the flash-driver name as well as the commands
@ -1192,4 +1160,5 @@ struct flash_driver nrf51_flash = {
.auto_probe = nrf5_auto_probe,
.erase_check = default_flash_blank_check,
.protect_check = nrf5_protect_check,
.free_driver_priv = nrf5_free_driver_priv,
};

1586
src/flash/nor/psoc5lp.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -54,6 +54,7 @@ const struct flash_device flash_devices[] = {
FLASH_ID("sp s25fl164k", 0xd8, 0xc7, 0x00174001, 0x100, 0x10000, 0x800000),
FLASH_ID("sp s25fl128", 0xd8, 0xc7, 0x00182001, 0x100, 0x10000, 0x1000000),
FLASH_ID("sp s25fl256", 0xd8, 0xc7, 0x00190201, 0x100, 0x10000, 0x2000000),
FLASH_ID("cy s25fl256", 0xd8, 0xc7, 0x00196001, 0x100, 0x10000, 0x2000000),
FLASH_ID("atmel 25f512", 0x52, 0xc7, 0x0065001f, 0x80, 0x8000, 0x10000),
FLASH_ID("atmel 25f1024", 0x52, 0x62, 0x0060001f, 0x100, 0x8000, 0x20000),
FLASH_ID("atmel 25f2048", 0x52, 0x62, 0x0063001f, 0x100, 0x10000, 0x40000),

View File

@ -585,8 +585,10 @@ static int stm32x_write_block(struct flash_bank *bank, const uint8_t *buffer,
retval = target_write_buffer(target, write_algorithm->address,
sizeof(stm32x_flash_write_code), stm32x_flash_write_code);
if (retval != ERROR_OK)
if (retval != ERROR_OK) {
target_free_working_area(target, write_algorithm);
return retval;
}
/* memory buffer */
while (target_alloc_working_area_try(target, buffer_size, &source) != ERROR_OK) {

View File

@ -252,6 +252,8 @@ static int stm32x_wait_status_busy(struct flash_bank *bank, int timeout)
/* Clear but report errors */
if (status & FLASH_ERROR) {
if (retval == ERROR_OK)
retval = ERROR_FAIL;
/* If this operation fails, we ignore it and report the original
* retval
*/
@ -597,8 +599,10 @@ static int stm32x_write_block(struct flash_bank *bank, const uint8_t *buffer,
retval = target_write_buffer(target, write_algorithm->address,
sizeof(stm32x_flash_write_code),
stm32x_flash_write_code);
if (retval != ERROR_OK)
if (retval != ERROR_OK) {
target_free_working_area(target, write_algorithm);
return retval;
}
/* memory buffer */
while (target_alloc_working_area_try(target, buffer_size, &source) != ERROR_OK) {

View File

@ -64,7 +64,7 @@
#define FLASH_WRPERR (1 << 17) /* Write protection error */
#define FLASH_PGSERR (1 << 18) /* Programming sequence error */
#define FLASH_STRBERR (1 << 19) /* Strobe error */
#define FLASH_INCERR (1 << 21) /* Increment error */
#define FLASH_INCERR (1 << 21) /* Inconsistency error */
#define FLASH_OPERR (1 << 22) /* Operation error */
#define FLASH_RDPERR (1 << 23) /* Read Protection error */
#define FLASH_RDSERR (1 << 24) /* Secure Protection error */
@ -220,6 +220,8 @@ static int stm32x_wait_status_busy(struct flash_bank *bank, int timeout)
/* Clear error + EOP flags but report errors */
if (status & FLASH_ERROR) {
if (retval == ERROR_OK)
retval = ERROR_FAIL;
/* If this operation fails, we ignore it and report the original retval */
target_write_u32(target, stm32x_get_flash_reg(bank, FLASH_CCR), status);
}
@ -495,7 +497,7 @@ static int stm32x_erase(struct flash_bank *bank, int first, int last)
retval = stm32x_wait_status_busy(bank, FLASH_ERASE_TIMEOUT);
if (retval != ERROR_OK) {
LOG_ERROR("erase time-out error sector %d", i);
LOG_ERROR("erase time-out or operation error sector %d", i);
return retval;
}
bank->sectors[i].is_erased = 1;
@ -581,8 +583,10 @@ static int stm32x_write_block(struct flash_bank *bank, const uint8_t *buffer,
retval = target_write_buffer(target, write_algorithm->address,
sizeof(stm32x_flash_write_code),
stm32x_flash_write_code);
if (retval != ERROR_OK)
if (retval != ERROR_OK) {
target_free_working_area(target, write_algorithm);
return retval;
}
/* memory buffer */
while (target_alloc_working_area_try(target, buffer_size, &source) != ERROR_OK) {

View File

@ -187,6 +187,8 @@ static int stm32l4_wait_status_busy(struct flash_bank *bank, int timeout)
/* Clear but report errors */
if (status & FLASH_ERROR) {
if (retval == ERROR_OK)
retval = ERROR_FAIL;
/* If this operation fails, we ignore it and report the original
* retval
*/
@ -474,8 +476,10 @@ static int stm32l4_write_block(struct flash_bank *bank, const uint8_t *buffer,
retval = target_write_buffer(target, write_algorithm->address,
sizeof(stm32l4_flash_write_code),
stm32l4_flash_write_code);
if (retval != ERROR_OK)
if (retval != ERROR_OK) {
target_free_working_area(target, write_algorithm);
return retval;
}
/* memory buffer */
while (target_alloc_working_area_try(target, buffer_size, &source) !=

View File

@ -146,7 +146,7 @@ static const struct stm32lx_rev stm32_425_revs[] = {
{ 0x1000, "A" }, { 0x2000, "B" }, { 0x2008, "Y" },
};
static const struct stm32lx_rev stm32_427_revs[] = {
{ 0x1000, "A" }, { 0x1018, "Y" }, { 0x1038, "X" },
{ 0x1000, "A" }, { 0x1018, "Y" }, { 0x1038, "X" }, { 0x10f8, "V" },
};
static const struct stm32lx_rev stm32_429_revs[] = {
{ 0x1000, "A" }, { 0x1018, "Z" },

View File

@ -288,24 +288,6 @@ COMMAND_HANDLER(handle_flash_erase_address_command)
return retval;
}
static int flash_check_sector_parameters(struct command_context *cmd_ctx,
uint32_t first, uint32_t last, uint32_t num_sectors)
{
if (!(first <= last)) {
command_print(cmd_ctx, "ERROR: "
"first sector must be <= last sector");
return ERROR_FAIL;
}
if (!(last <= (num_sectors - 1))) {
command_print(cmd_ctx, "ERROR: last sector must be <= %" PRIu32,
num_sectors - 1);
return ERROR_FAIL;
}
return ERROR_OK;
}
COMMAND_HANDLER(handle_flash_erase_command)
{
if (CMD_ARGC != 3)
@ -327,9 +309,18 @@ COMMAND_HANDLER(handle_flash_erase_command)
else
COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], last);
retval = flash_check_sector_parameters(CMD_CTX, first, last, p->num_sectors);
if (retval != ERROR_OK)
return retval;
if (!(first <= last)) {
command_print(CMD_CTX, "ERROR: "
"first sector must be <= last");
return ERROR_FAIL;
}
if (!(last <= (uint32_t)(p->num_sectors - 1))) {
command_print(CMD_CTX, "ERROR: "
"last sector must be <= %" PRIu32,
p->num_sectors - 1);
return ERROR_FAIL;
}
struct duration bench;
duration_start(&bench);
@ -375,15 +366,28 @@ COMMAND_HANDLER(handle_flash_protect_command)
bool set;
COMMAND_PARSE_ON_OFF(CMD_ARGV[3], set);
retval = flash_check_sector_parameters(CMD_CTX, first, last, num_blocks);
if (retval != ERROR_OK)
return retval;
if (!(first <= last)) {
command_print(CMD_CTX, "ERROR: "
"first %s must be <= last",
(p->num_prot_blocks) ? "block" : "sector");
return ERROR_FAIL;
}
if (!(last <= (uint32_t)(num_blocks - 1))) {
command_print(CMD_CTX, "ERROR: "
"last %s must be <= %" PRIu32,
(p->num_prot_blocks) ? "block" : "sector",
num_blocks - 1);
return ERROR_FAIL;
}
retval = flash_driver_protect(p, set, first, last);
if (retval == ERROR_OK) {
command_print(CMD_CTX, "%s protection for sectors %" PRIu32
command_print(CMD_CTX, "%s protection for %s %" PRIu32
" through %" PRIu32 " on flash bank %d",
(set) ? "set" : "cleared", first, last, p->bank_number);
(set) ? "set" : "cleared",
(p->num_prot_blocks) ? "blocks" : "sectors",
first, last, p->bank_number);
}
return retval;
@ -502,7 +506,7 @@ COMMAND_HANDLER(handle_flash_fill_command)
if (count == 0)
return ERROR_OK;
if (address + count >= bank->base + bank->size) {
if (address + count * wordsize > bank->base + bank->size) {
LOG_ERROR("Cannot cross flash bank borders");
return ERROR_FAIL;
}

View File

@ -151,6 +151,7 @@ static int tms470_read_part_info(struct flash_bank *bank)
if (bank->sectors) {
free(bank->sectors);
bank->sectors = NULL;
bank->num_sectors = 0;
}
/*
@ -754,9 +755,6 @@ static int tms470_erase_sector(struct flash_bank *bank, int sector)
target_write_u32(target, 0xFFFFFFDC, glbctrl);
LOG_DEBUG("set glbctrl = 0x%08" PRIx32 "", glbctrl);
if (result == ERROR_OK)
bank->sectors[sector].is_erased = 1;
return result;
}
@ -1044,7 +1042,6 @@ static int tms470_erase_check(struct flash_bank *bank)
* an attempt to reduce the JTAG overhead.
*/
for (sector = 0; sector < bank->num_sectors; sector++) {
if (bank->sectors[sector].is_erased != 1) {
uint32_t i, addr = bank->base + bank->sectors[sector].offset;
LOG_INFO("checking flash bank %d sector %d", tms470_info->ordinal, sector);
@ -1054,19 +1051,10 @@ static int tms470_erase_check(struct flash_bank *bank)
bank->sectors[sector].is_erased = 1;
for (i = 0; i < bank->sectors[sector].size; i++) {
if (buffer[i] != 0xff) {
LOG_WARNING("tms470 bank %d, sector %d, not erased.",
tms470_info->ordinal,
sector);
LOG_WARNING(
"at location 0x%08" PRIx32 ": flash data is 0x%02x.",
addr + i,
buffer[i]);
bank->sectors[sector].is_erased = 0;
break;
}
}
}
if (bank->sectors[sector].is_erased != 1) {
result = ERROR_FLASH_SECTOR_NOT_ERASED;
break;

View File

@ -46,8 +46,13 @@ static void virtual_update_bank_info(struct flash_bank *bank)
bank->bus_width = master_bank->bus_width;
bank->erased_value = master_bank->erased_value;
bank->default_padded_value = master_bank->default_padded_value;
bank->write_start_alignment = master_bank->write_start_alignment;
bank->write_end_alignment = master_bank->write_end_alignment;
bank->minimal_write_gap = master_bank->minimal_write_gap;
bank->num_sectors = master_bank->num_sectors;
bank->sectors = master_bank->sectors;
bank->num_prot_blocks = master_bank->num_prot_blocks;
bank->prot_blocks = master_bank->prot_blocks;
}
FLASH_BANK_COMMAND_HANDLER(virtual_flash_bank_command)

View File

@ -2289,6 +2289,7 @@ get_delay:
static int aice_usb_set_clock(int set_clock)
{
if (set_clock & AICE_TCK_CONTROL_TCK_SCAN) {
if (aice_write_ctrl(AICE_WRITE_CTRL_TCK_CONTROL,
AICE_TCK_CONTROL_TCK_SCAN) != ERROR_OK)
return ERROR_FAIL;
@ -2321,6 +2322,7 @@ static int aice_usb_set_clock(int set_clock)
LOG_ERROR("User specifies higher jtag clock than TCK_SCAN clock");
return ERROR_FAIL;
}
}
if (aice_write_ctrl(AICE_WRITE_CTRL_TCK_CONTROL, set_clock) != ERROR_OK)
return ERROR_FAIL;

View File

@ -71,6 +71,7 @@
/* Constants for AICE command WRITE_CTRL:TCK_CONTROL */
#define AICE_TCK_CONTROL_TCK3048 0x08
#define AICE_TCK_CONTROL_TCK_SCAN 0x10
/* Constants for AICE command WRITE_CTRL:JTAG_PIN_CONTROL */
#define AICE_JTAG_PIN_CONTROL_SRST 0x01

View File

@ -1843,7 +1843,7 @@ void adapter_deassert_reset(void)
LOG_ERROR("transport is not selected");
}
int adapter_config_trace(bool enabled, enum tpio_pin_protocol pin_protocol,
int adapter_config_trace(bool enabled, enum tpiu_pin_protocol pin_protocol,
uint32_t port_size, unsigned int *trace_freq)
{
if (jtag->config_trace)

View File

@ -156,10 +156,12 @@ endif
if IMX_GPIO
DRIVERFILES += %D%/imx_gpio.c
endif
if KITPROG
DRIVERFILES += %D%/kitprog.c
endif
if XDS110
DRIVERFILES += %D%/xds110.c
endif
DRIVERHEADERS = \
%D%/bitbang.h \

View File

@ -729,6 +729,20 @@ static void cmsis_dap_swd_read_reg(uint8_t cmd, uint32_t *value, uint32_t ap_del
cmsis_dap_swd_queue_cmd(cmd, value, 0);
}
static int cmsis_dap_get_serial_info(void)
{
uint8_t *data;
int retval = cmsis_dap_cmd_DAP_Info(INFO_ID_SERNUM, &data);
if (retval != ERROR_OK)
return retval;
if (data[0]) /* strlen */
LOG_INFO("CMSIS-DAP: Serial# = %s", &data[1]);
return ERROR_OK;
}
static int cmsis_dap_get_version_info(void)
{
uint8_t *data;
@ -802,8 +816,7 @@ static int cmsis_dap_swd_switch_seq(enum swd_special_seq seq)
/* When we are reconnecting, DAP_Connect needs to be rerun, at
* least on Keil ULINK-ME */
retval = cmsis_dap_cmd_DAP_Connect(seq == LINE_RESET || seq == JTAG_TO_SWD ?
CONNECT_SWD : CONNECT_JTAG);
retval = cmsis_dap_cmd_DAP_Connect(CONNECT_SWD);
if (retval != ERROR_OK)
return retval;
}
@ -842,17 +855,6 @@ static int cmsis_dap_swd_open(void)
{
int retval;
if (cmsis_dap_handle == NULL) {
/* SWD init */
retval = cmsis_dap_usb_open();
if (retval != ERROR_OK)
return retval;
retval = cmsis_dap_get_caps_info();
if (retval != ERROR_OK)
return retval;
}
if (!(cmsis_dap_handle->caps & INFO_CAPS_SWD)) {
LOG_ERROR("CMSIS-DAP: SWD not supported");
return ERROR_JTAG_DEVICE_ERROR;
@ -873,15 +875,6 @@ static int cmsis_dap_init(void)
int retval;
uint8_t *data;
if (swd_mode) {
retval = cmsis_dap_swd_open();
if (retval != ERROR_OK)
return retval;
}
if (cmsis_dap_handle == NULL) {
/* JTAG init */
retval = cmsis_dap_usb_open();
if (retval != ERROR_OK)
return retval;
@ -890,6 +883,21 @@ static int cmsis_dap_init(void)
if (retval != ERROR_OK)
return retval;
retval = cmsis_dap_get_version_info();
if (retval != ERROR_OK)
return retval;
retval = cmsis_dap_get_serial_info();
if (retval != ERROR_OK)
return retval;
if (swd_mode) {
retval = cmsis_dap_swd_open();
if (retval != ERROR_OK)
return retval;
}
if (cmsis_dap_handle == NULL) {
/* Connect in JTAG mode */
if (!(cmsis_dap_handle->caps & INFO_CAPS_JTAG)) {
LOG_ERROR("CMSIS-DAP: JTAG not supported");
@ -903,10 +911,6 @@ static int cmsis_dap_init(void)
LOG_INFO("CMSIS-DAP: Interface Initialised (JTAG)");
}
retval = cmsis_dap_get_version_info();
if (retval != ERROR_OK)
return retval;
/* INFO_ID_PKT_SZ - short */
retval = cmsis_dap_cmd_DAP_Info(INFO_ID_PKT_SZ, &data);
if (retval != ERROR_OK)
@ -1458,6 +1462,12 @@ static void cmsis_dap_execute_stableclocks(struct jtag_command *cmd)
cmsis_dap_stableclocks(cmd->cmd.runtest->num_cycles);
}
static void cmsis_dap_execute_tms(struct jtag_command *cmd)
{
DEBUG_JTAG_IO("TMS: %d bits", cmd->cmd.tms->num_bits);
cmsis_dap_cmd_DAP_SWJ_Sequence(cmd->cmd.tms->num_bits, cmd->cmd.tms->bits);
}
/* TODO: Is there need to call cmsis_dap_flush() for the JTAG_PATHMOVE,
* JTAG_RUNTEST, JTAG_STABLECLOCKS? */
static void cmsis_dap_execute_command(struct jtag_command *cmd)
@ -1488,6 +1498,8 @@ static void cmsis_dap_execute_command(struct jtag_command *cmd)
cmsis_dap_execute_stableclocks(cmd);
break;
case JTAG_TMS:
cmsis_dap_execute_tms(cmd);
break;
default:
LOG_ERROR("BUG: unknown JTAG command type 0x%X encountered", cmd->type);
exit(-1);
@ -1650,6 +1662,7 @@ static const char * const cmsis_dap_transport[] = { "swd", "jtag", NULL };
struct jtag_interface cmsis_dap_interface = {
.name = "cmsis-dap",
.supported = DEBUG_CAP_TMS_SEQ,
.commands = cmsis_dap_command_handlers,
.swd = &cmsis_dap_swd_driver,
.transports = cmsis_dap_transport,

View File

@ -1263,7 +1263,7 @@ static bool check_trace_freq(struct jaylink_swo_speed speed,
return false;
}
static int config_trace(bool enabled, enum tpio_pin_protocol pin_protocol,
static int config_trace(bool enabled, enum tpiu_pin_protocol pin_protocol,
uint32_t port_size, unsigned int *trace_freq)
{
int ret;
@ -1275,7 +1275,7 @@ static int config_trace(bool enabled, enum tpio_pin_protocol pin_protocol,
return ERROR_FAIL;
}
if (pin_protocol != ASYNC_UART) {
if (pin_protocol != TPIU_PIN_PROTOCOL_ASYNC_UART) {
LOG_ERROR("Selected pin protocol is not supported.");
return ERROR_FAIL;
}

View File

@ -204,23 +204,20 @@ static int jtag_vpi_queue_tdi_xfer(uint8_t *bits, int nb_bits, int tap_shift)
static int jtag_vpi_queue_tdi(uint8_t *bits, int nb_bits, int tap_shift)
{
int nb_xfer = DIV_ROUND_UP(nb_bits, XFERT_MAX_SIZE * 8);
uint8_t *xmit_buffer = bits;
int xmit_nb_bits = nb_bits;
int i = 0;
int retval;
while (nb_xfer) {
if (nb_xfer == 1) {
retval = jtag_vpi_queue_tdi_xfer(&xmit_buffer[i], xmit_nb_bits, tap_shift);
retval = jtag_vpi_queue_tdi_xfer(bits, nb_bits, tap_shift);
if (retval != ERROR_OK)
return retval;
} else {
retval = jtag_vpi_queue_tdi_xfer(&xmit_buffer[i], XFERT_MAX_SIZE * 8, NO_TAP_SHIFT);
retval = jtag_vpi_queue_tdi_xfer(bits, XFERT_MAX_SIZE * 8, NO_TAP_SHIFT);
if (retval != ERROR_OK)
return retval;
xmit_nb_bits -= XFERT_MAX_SIZE * 8;
i += XFERT_MAX_SIZE;
nb_bits -= XFERT_MAX_SIZE * 8;
if (bits)
bits += XFERT_MAX_SIZE;
}
nb_xfer--;
@ -318,7 +315,7 @@ static int jtag_vpi_runtest(int cycles, tap_state_t state)
if (retval != ERROR_OK)
return retval;
retval = jtag_vpi_queue_tdi(NULL, cycles, NO_TAP_SHIFT);
retval = jtag_vpi_queue_tdi(NULL, cycles, TAP_SHIFT);
if (retval != ERROR_OK)
return retval;

View File

@ -888,13 +888,11 @@ COMMAND_HANDLER(kitprog_handle_acquire_psoc_command)
COMMAND_HANDLER(kitprog_handle_serial_command)
{
if (CMD_ARGC == 1) {
size_t len = strlen(CMD_ARGV[0]);
kitprog_serial = calloc(len + 1, sizeof(char));
kitprog_serial = strdup(CMD_ARGV[0]);
if (kitprog_serial == NULL) {
LOG_ERROR("Failed to allocate memory for the serial number");
return ERROR_FAIL;
}
strncpy(kitprog_serial, CMD_ARGV[0], len + 1);
} else {
LOG_ERROR("expected exactly one argument to kitprog_serial <serial-number>");
return ERROR_FAIL;

View File

@ -2194,12 +2194,13 @@ error_open:
return ERROR_FAIL;
}
int stlink_config_trace(void *handle, bool enabled, enum tpio_pin_protocol pin_protocol,
int stlink_config_trace(void *handle, bool enabled, enum tpiu_pin_protocol pin_protocol,
uint32_t port_size, unsigned int *trace_freq)
{
struct stlink_usb_handle_s *h = handle;
if (enabled && (h->jtag_api < 2 || pin_protocol != ASYNC_UART)) {
if (enabled && (h->jtag_api < 2 ||
pin_protocol != TPIU_PIN_PROTOCOL_ASYNC_UART)) {
LOG_ERROR("The attached ST-LINK version doesn't support this trace mode");
return ERROR_FAIL;
}

View File

@ -58,11 +58,11 @@
/*
* Helper func to determine if gpio number valid
*
* Assume here that there will be less than 1000 gpios on a system
* Assume here that there will be less than 10000 gpios on a system
*/
static int is_gpio_valid(int gpio)
{
return gpio >= 0 && gpio < 1000;
return gpio >= 0 && gpio < 10000;
}
/*
@ -89,7 +89,7 @@ static int open_write_close(const char *name, const char *valstr)
*/
static void unexport_sysfs_gpio(int gpio)
{
char gpiostr[4];
char gpiostr[5];
if (!is_gpio_valid(gpio))
return;
@ -113,7 +113,7 @@ static void unexport_sysfs_gpio(int gpio)
static int setup_sysfs_gpio(int gpio, int is_output, int init_high)
{
char buf[40];
char gpiostr[4];
char gpiostr[5];
int ret;
if (!is_gpio_valid(gpio))

View File

@ -445,6 +445,7 @@ static void ublast_queue_bytes(uint8_t *bytes, int nb_bytes)
* ublast_tms_seq - write a TMS sequence transition to JTAG
* @bits: TMS bits to be written (bit0, bit1 .. bitN)
* @nb_bits: number of TMS bits (between 1 and 8)
* @skip: number of TMS bits to skip at the beginning of the series
*
* Write a serie of TMS transitions, where each transition consists in :
* - writing out TCK=0, TMS=<new_state>, TDI=<???>
@ -452,12 +453,12 @@ static void ublast_queue_bytes(uint8_t *bytes, int nb_bytes)
* The function ensures that at the end of the sequence, the clock (TCK) is put
* low.
*/
static void ublast_tms_seq(const uint8_t *bits, int nb_bits)
static void ublast_tms_seq(const uint8_t *bits, int nb_bits, int skip)
{
int i;
DEBUG_JTAG_IO("(bits=%02x..., nb_bits=%d)", bits[0], nb_bits);
for (i = 0; i < nb_bits; i++)
for (i = skip; i < nb_bits; i++)
ublast_clock_tms((bits[i / 8] >> (i % 8)) & 0x01);
ublast_idle_clock();
}
@ -469,7 +470,7 @@ static void ublast_tms_seq(const uint8_t *bits, int nb_bits)
static void ublast_tms(struct tms_command *cmd)
{
DEBUG_JTAG_IO("(num_bits=%d)", cmd->num_bits);
ublast_tms_seq(cmd->bits, cmd->num_bits);
ublast_tms_seq(cmd->bits, cmd->num_bits, 0);
}
/**
@ -501,11 +502,12 @@ static void ublast_path_move(struct pathmove_command *cmd)
/**
* ublast_state_move - move JTAG state to the target state
* @state: the target state
* @skip: number of bits to skip at the beginning of the path
*
* Input the correct TMS sequence to the JTAG TAP so that we end up in the
* target state. This assumes the current state (tap_get_state()) is correct.
*/
static void ublast_state_move(tap_state_t state)
static void ublast_state_move(tap_state_t state, int skip)
{
uint8_t tms_scan;
int tms_len;
@ -516,7 +518,7 @@ static void ublast_state_move(tap_state_t state)
return;
tms_scan = tap_get_tms_path(tap_get_state(), state);
tms_len = tap_get_tms_path_len(tap_get_state(), state);
ublast_tms_seq(&tms_scan, tms_len);
ublast_tms_seq(&tms_scan, tms_len, skip);
tap_set_state(state);
}
@ -688,9 +690,9 @@ static void ublast_runtest(int cycles, tap_state_t state)
{
DEBUG_JTAG_IO("%s(cycles=%i, end_state=%d)", __func__, cycles, state);
ublast_state_move(TAP_IDLE);
ublast_state_move(TAP_IDLE, 0);
ublast_queue_tdi(NULL, cycles, SCAN_OUT);
ublast_state_move(state);
ublast_state_move(state, 0);
}
static void ublast_stableclocks(int cycles)
@ -720,9 +722,9 @@ static int ublast_scan(struct scan_command *cmd)
scan_bits = jtag_build_buffer(cmd, &buf);
if (cmd->ir_scan)
ublast_state_move(TAP_IRSHIFT);
ublast_state_move(TAP_IRSHIFT, 0);
else
ublast_state_move(TAP_DRSHIFT);
ublast_state_move(TAP_DRSHIFT, 0);
log_buf = hexdump(buf, DIV_ROUND_UP(scan_bits, 8));
DEBUG_JTAG_IO("%s(scan=%s, type=%s, bits=%d, buf=[%s], end_state=%d)", __func__,
@ -733,20 +735,15 @@ static int ublast_scan(struct scan_command *cmd)
ublast_queue_tdi(buf, scan_bits, type);
/*
* As our JTAG is in an unstable state (IREXIT1 or DREXIT1), move it
* forward to a stable IRPAUSE or DRPAUSE.
*/
ublast_clock_tms(0);
if (cmd->ir_scan)
tap_set_state(TAP_IRPAUSE);
else
tap_set_state(TAP_DRPAUSE);
ret = jtag_read_buffer(buf, cmd);
if (buf)
free(buf);
ublast_state_move(cmd->end_state);
/*
* ublast_queue_tdi sends the last bit with TMS=1. We are therefore
* already in Exit1-DR/IR and have to skip the first step on our way
* to end_state.
*/
ublast_state_move(cmd->end_state, 1);
return ret;
}
@ -776,7 +773,7 @@ static void ublast_initial_wipeout(void)
/*
* Put JTAG in RESET state (five 1 on TMS)
*/
ublast_tms_seq(&tms_reset, 5);
ublast_tms_seq(&tms_reset, 5, 0);
tap_set_state(TAP_RESET);
}
@ -805,7 +802,7 @@ static int ublast_execute_queue(void)
ublast_stableclocks(cmd->cmd.stableclocks->num_cycles);
break;
case JTAG_TLR_RESET:
ublast_state_move(cmd->cmd.statemove->end_state);
ublast_state_move(cmd->cmd.statemove->end_state, 0);
break;
case JTAG_PATHMOVE:
ublast_path_move(cmd->cmd.pathmove);

1973
src/jtag/drivers/xds110.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -191,7 +191,7 @@ int hl_interface_override_target(const char **targetname)
return ERROR_FAIL;
}
int hl_interface_config_trace(bool enabled, enum tpio_pin_protocol pin_protocol,
int hl_interface_config_trace(bool enabled, enum tpiu_pin_protocol pin_protocol,
uint32_t port_size, unsigned int *trace_freq)
{
if (hl_if.layout->api->config_trace)

View File

@ -91,7 +91,7 @@ struct hl_layout_api_s {
* its maximum supported rate there
* @returns ERROR_OK on success, an error code on failure.
*/
int (*config_trace)(void *handle, bool enabled, enum tpio_pin_protocol pin_protocol,
int (*config_trace)(void *handle, bool enabled, enum tpiu_pin_protocol pin_protocol,
uint32_t port_size, unsigned int *trace_freq);
/**
* Poll for new trace data

View File

@ -309,7 +309,7 @@ struct jtag_interface {
* its maximum supported rate there
* @returns ERROR_OK on success, an error code on failure.
*/
int (*config_trace)(bool enabled, enum tpio_pin_protocol pin_protocol,
int (*config_trace)(bool enabled, enum tpiu_pin_protocol pin_protocol,
uint32_t port_size, unsigned int *trace_freq);
/**
@ -328,7 +328,7 @@ extern const char * const jtag_only[];
void adapter_assert_reset(void);
void adapter_deassert_reset(void);
int adapter_config_trace(bool enabled, enum tpio_pin_protocol pin_protocol,
int adapter_config_trace(bool enabled, enum tpiu_pin_protocol pin_protocol,
uint32_t port_size, unsigned int *trace_freq);
int adapter_poll_trace(uint8_t *buf, size_t *size);

View File

@ -132,6 +132,9 @@ extern struct jtag_interface kitprog_interface;
#if BUILD_IMX_GPIO == 1
extern struct jtag_interface imx_gpio_interface;
#endif
#if BUILD_XDS110 == 1
extern struct jtag_interface xds110_interface;
#endif
#endif /* standard drivers */
/**
@ -234,6 +237,9 @@ struct jtag_interface *jtag_interfaces[] = {
#if BUILD_IMX_GPIO == 1
&imx_gpio_interface,
#endif
#if BUILD_XDS110 == 1
&xds110_interface,
#endif
#endif /* standard drivers */
NULL,
};

Some files were not shown because too many files have changed in this diff Show More