flash/nor: Add support for TI CC26xx/CC13xx flash
Added cc26xx flash driver to support the TI CC26xx and CC13xx microcontrollers. Driver is capable of determining which MCU is connected and configures itself accordingly. Added config files for four specific variants: CC26x0, CC13x0, CC26x2, and CC13x2. Note that the flash loader code is based on the sources used to support flash in Code Composer Studio and Uniflash from TI. Removed cc26xx.cfg file made obsolete by this patch. Change-Id: Ie2b0f74f8af7517a9184704b839677d1c9787862 Signed-off-by: Edward Fewell <efewell@ti.com> Reviewed-on: http://openocd.zylin.com/4358 Tested-by: jenkins Reviewed-by: Tomas Vanek <vanekt@fbl.cz> Reviewed-by: Fredrik Hederstierna <fredrik@hederstierna.com>
This commit is contained in:
committed by
Tomas Vanek
parent
06123153f3
commit
7b03129916
@@ -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
|
||||
@@ -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
@@ -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
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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 */
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
@@ -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)
|
||||
;
|
||||
}
|
||||
@@ -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)
|
||||
;
|
||||
}
|
||||
Reference in New Issue
Block a user