arm/tms570: include hardware initialization and selftest based on Ti HalCoGen generated files.

The configuration is specific for TMS570LS3137 based HDK.
Pins configuration can be easily changed in

  rtems/c/src/lib/libbsp/arm/tms570/hwinit/init_pinmux.c

file.

The list tms570_selftest_par_list in the file

  rtems/c/src/lib/libbsp/arm/tms570/hwinit/bspstarthooks-hwinit.c

specifies peripherals which health status is examined
by parity self-test at BSP start-up. It can be easily
modified for other TMS570 family members variants same
as the selection of other tests in bspstarthooks-hwinit.c.
This commit is contained in:
Pavel Pisa
2016-09-22 09:50:59 +02:00
parent 22ab88c486
commit 8671786934
16 changed files with 3519 additions and 0 deletions

View File

@@ -0,0 +1,422 @@
#include <stdint.h>
#include <bsp.h>
#include <bsp/start.h>
#include <bsp/tms570.h>
#include "tms570_selftest.h"
#include "tms570_selftest_parity.h"
#include "tms570_hwinit.h"
void bsp_start_hook_0_done( void );
static inline
int tms570_running_from_tcram( void )
{
void *fncptr = (void*)bsp_start_hook_0;
return ( fncptr >= (void*)TMS570_TCRAM_START_PTR ) &&
( fncptr < (void*)TMS570_TCRAM_WINDOW_END_PTR );
}
static inline
int tms570_running_from_sdram( void )
{
void *fncptr = (void*)bsp_start_hook_0;
return ( ( (void*)fncptr >= (void*)TMS570_SDRAM_START_PTR ) &&
( (void*)fncptr < (void*)TMS570_SDRAM_WINDOW_END_PTR ) );
}
#define PBIST_March13N_SP 0x00000008U /**< March13 N Algo for 1 Port mem */
BSP_START_TEXT_SECTION void bsp_start_hook_0( void )
{
/*
* Work Around for Errata DEVICE#140: ( Only on Rev A silicon)
*
* Errata Description:
* The Core Compare Module(CCM-R4) may cause nERROR to be asserted after a cold power-on
* Workaround:
* Clear ESM Group2 Channel 2 error in ESMSR2 and Compare error in CCMSR register
*/
if ( TMS570_SYS1.DEVID == 0x802AAD05U ) {
_esmCcmErrorsClear_();
}
/* Enable CPU Event Export */
/* This allows the CPU to signal any single-bit or double-bit errors detected
* by its ECC logic for accesses to program flash or data RAM.
*/
_coreEnableEventBusExport_();
/* Workaround for Errata CORTEXR4 66 */
_errata_CORTEXR4_66_();
/* Workaround for Errata CORTEXR4 57 */
_errata_CORTEXR4_57_();
/* check for power-on reset condition */
/*SAFETYMCUSW 139 S MR:13.7 <APPROVED> "Hardware status bit read check" */
if ( ( TMS570_SYS1.SYSESR & TMS570_SYS1_SYSESR_PORST ) != 0U ) {
/* clear all reset status flags */
TMS570_SYS1.SYSESR = 0xFFFFU;
/* continue with normal start-up sequence */
}
/*SAFETYMCUSW 139 S MR:13.7 <APPROVED> "Hardware status bit read check" */
else if ( ( TMS570_SYS1.SYSESR & TMS570_SYS1_SYSESR_OSCRST ) != 0U ) {
/* Reset caused due to oscillator failure.
Add user code here to handle oscillator failure */
}
/*SAFETYMCUSW 139 S MR:13.7 <APPROVED> "Hardware status bit read check" */
else if ( ( TMS570_SYS1.SYSESR & TMS570_SYS1_SYSESR_WDRST ) != 0U ) {
/* Reset caused due
* 1) windowed watchdog violation - Add user code here to handle watchdog violation.
* 2) ICEPICK Reset - After loading code via CCS / System Reset through CCS
*/
/* Check the WatchDog Status register */
if ( TMS570_RTI.WDSTATUS != 0U ) {
/* Add user code here to handle watchdog violation. */
/* Clear the Watchdog reset flag in Exception Status register */
TMS570_SYS1.SYSESR = TMS570_SYS1_SYSESR_WDRST;
} else {
/* Clear the ICEPICK reset flag in Exception Status register */
TMS570_SYS1.SYSESR = TMS570_SYS1_SYSESR_WDRST;
}
}
/*SAFETYMCUSW 139 S MR:13.7 <APPROVED> "Hardware status bit read check" */
else if ( ( TMS570_SYS1.SYSESR & TMS570_SYS1_SYSESR_CPURST ) != 0U ) {
/* Reset caused due to CPU reset.
CPU reset can be caused by CPU self-test completion, or
by toggling the "CPU RESET" bit of the CPU Reset Control Register. */
/* clear all reset status flags */
TMS570_SYS1.SYSESR = TMS570_SYS1_SYSESR_CPURST;
}
/*SAFETYMCUSW 139 S MR:13.7 <APPROVED> "Hardware status bit read check" */
else if ( ( TMS570_SYS1.SYSESR & TMS570_SYS1_SYSESR_SWRST ) != 0U ) {
/* Reset caused due to software reset.
Add user code to handle software reset. */
} else {
/* Reset caused by nRST being driven low externally.
Add user code to handle external reset. */
}
/*
* Check if there were ESM group3 errors during power-up.
* These could occur during eFuse auto-load or during reads from flash OTP
* during power-up. Device operation is not reliable and not recommended
* in this case.
* An ESM group3 error only drives the nERROR pin low. An external circuit
* that monitors the nERROR pin must take the appropriate action to ensure that
* the system is placed in a safe state, as determined by the application.
*/
if ( ( TMS570_ESM.SR[ 2 ] ) != 0U ) {
/*SAFETYMCUSW 5 C MR:NA <APPROVED> "for(;;) can be removed by adding "# if 0" and "# endif" in the user codes above and below" */
/*SAFETYMCUSW 26 S MR:NA <APPROVED> "for(;;) can be removed by adding "# if 0" and "# endif" in the user codes above and below" */
/*SAFETYMCUSW 28 D MR:NA <APPROVED> "for(;;) can be removed by adding "# if 0" and "# endif" in the user codes above and below" */
for (;; ) {
} /* Wait */
}
/* Initialize System - Clock, Flash settings with Efuse self check */
tms570_system_hw_init();
/* Workaround for Errata PBIST#4 */
/* FIXME */
//errata_PBIST_4();
/*
* Run a diagnostic check on the memory self-test controller.
* This function chooses a RAM test algorithm and runs it on an on-chip ROM.
* The memory self-test is expected to fail. The function ensures that the PBIST controller
* is capable of detecting and indicating a memory self-test failure.
*/
tms570_pbist_self_check();
/* Run PBIST on STC ROM */
tms570_pbist_run( (uint32_t) STC_ROM_PBIST_RAM_GROUP,
( (uint32_t) PBIST_TripleReadSlow | (uint32_t) PBIST_TripleReadFast ) );
/* Wait for PBIST for STC ROM to be completed */
/*SAFETYMCUSW 28 D MR:NA <APPROVED> "Hardware status bit read check" */
while ( tms570_pbist_is_test_completed() != TRUE ) {
} /* Wait */
/* Check if PBIST on STC ROM passed the self-test */
if ( tms570_pbist_is_test_passed() != TRUE ) {
/* PBIST and STC ROM failed the self-test.
* Need custom handler to check the memory failure
* and to take the appropriate next step.
*/
tms570_pbist_fail();
}
/* Disable PBIST clocks and disable memory self-test mode */
tms570_pbist_stop();
/* Run PBIST on PBIST ROM */
tms570_pbist_run( (uint32_t) PBIST_ROM_PBIST_RAM_GROUP,
( (uint32_t) PBIST_TripleReadSlow | (uint32_t) PBIST_TripleReadFast ) );
/* Wait for PBIST for PBIST ROM to be completed */
/*SAFETYMCUSW 28 D MR:NA <APPROVED> "Hardware status bit read check" */
while ( tms570_pbist_is_test_completed() != TRUE ) {
} /* Wait */
/* Check if PBIST ROM passed the self-test */
if ( tms570_pbist_is_test_passed() != TRUE ) {
/* PBIST and STC ROM failed the self-test.
* Need custom handler to check the memory failure
* and to take the appropriate next step.
*/
tms570_pbist_fail();
}
/* Disable PBIST clocks and disable memory self-test mode */
tms570_pbist_stop();
if ( !tms570_running_from_tcram() ) {
/*
* The next sequence tests TCRAM, main TMS570 system operation RAM area.
* The tests are destructive, lead the first to fill memory by 0xc5c5c5c5
* and then to clear it to zero. The sequence is obliviously incompatible
* with RTEMS image running from TCRAM area (code clears itself).
*
* But TCRAM clear leads to overwrite of stack which is used to store
* value of bsp_start_hook_0 call return address from link register.
*
* If the bsp_start_hook_0 by jump to bsp_start_hook_0_done
* then generated C code does not use any variable which
* is stores on stack and code works OK even that memory
* is cleared during bsp_start_hook_0 execution.
*
* The last assumption is a little fragile in respect to
* code and compiler changes.
*/
/* Disable RAM ECC before doing PBIST for Main RAM */
_coreDisableRamEcc_();
/* Run PBIST on CPU RAM.
* The PBIST controller needs to be configured separately for single-port and dual-port SRAMs.
* The CPU RAM is a single-port memory. The actual "RAM Group" for all on-chip SRAMs is defined in the
* device datasheet.
*/
tms570_pbist_run( 0x08300020U, /* ESRAM Single Port PBIST */
(uint32_t) PBIST_March13N_SP );
/* Wait for PBIST for CPU RAM to be completed */
/*SAFETYMCUSW 28 D MR:NA <APPROVED> "Hardware status bit read check" */
while ( tms570_pbist_is_test_completed() != TRUE ) {
} /* Wait */
/* Check if CPU RAM passed the self-test */
if ( tms570_pbist_is_test_passed() != TRUE ) {
/* CPU RAM failed the self-test.
* Need custom handler to check the memory failure
* and to take the appropriate next step.
*/
tms570_pbist_fail();
}
/* Disable PBIST clocks and disable memory self-test mode */
tms570_pbist_stop();
/*
* Initialize CPU RAM.
* This function uses the system module's hardware for auto-initialization of memories and their
* associated protection schemes. The CPU RAM is initialized by setting bit 0 of the MSIENA register.
* Hence the value 0x1 passed to the function.
* This function will initialize the entire CPU RAM and the corresponding ECC locations.
*/
tms570_memory_init( 0x1U );
/*
* Enable ECC checking for TCRAM accesses.
* This function enables the CPU's ECC logic for accesses to B0TCM and B1TCM.
*/
_coreEnableRamEcc_();
} /* end of the code skipped for tms570_running_from_tcram() */
/* Start PBIST on all dual-port memories */
/* NOTE : Please Refer DEVICE DATASHEET for the list of Supported Dual port Memories.
PBIST test performed only on the user selected memories in HALCoGen's GUI SAFETY INIT tab.
*/
tms570_pbist_run( (uint32_t) 0x00000000U | /* EMAC RAM */
(uint32_t) 0x00000000U | /* USB RAM */
(uint32_t) 0x00000800U | /* DMA RAM */
(uint32_t) 0x00000200U | /* VIM RAM */
(uint32_t) 0x00000040U | /* MIBSPI1 RAM */
(uint32_t) 0x00000080U | /* MIBSPI3 RAM */
(uint32_t) 0x00000100U | /* MIBSPI5 RAM */
(uint32_t) 0x00000004U | /* CAN1 RAM */
(uint32_t) 0x00000008U | /* CAN2 RAM */
(uint32_t) 0x00000010U | /* CAN3 RAM */
(uint32_t) 0x00000400U | /* ADC1 RAM */
(uint32_t) 0x00020000U | /* ADC2 RAM */
(uint32_t) 0x00001000U | /* HET1 RAM */
(uint32_t) 0x00040000U | /* HET2 RAM */
(uint32_t) 0x00002000U | /* HTU1 RAM */
(uint32_t) 0x00080000U | /* HTU2 RAM */
(uint32_t) 0x00004000U | /* RTP RAM */
(uint32_t) 0x00008000U, /* FRAY RAM */
(uint32_t) PBIST_March13N_DP );
if ( !tms570_running_from_tcram() ) {
/* Test the CPU ECC mechanism for RAM accesses.
* The checkBxRAMECC functions cause deliberate single-bit and double-bit errors in TCRAM accesses
* by corrupting 1 or 2 bits in the ECC. Reading from the TCRAM location with a 2-bit error
* in the ECC causes a data abort exception. The data abort handler is written to look for
* deliberately caused exception and to return the code execution to the instruction
* following the one that caused the abort.
*/
tms570_check_tcram_ecc();
/* Wait for PBIST for CPU RAM to be completed */
/*SAFETYMCUSW 28 D MR:NA <APPROVED> "Hardware status bit read check" */
while ( tms570_pbist_is_test_completed() != TRUE ) {
} /* Wait */
/* Check if CPU RAM passed the self-test */
if ( tms570_pbist_is_test_passed() != TRUE ) {
/* CPU RAM failed the self-test.
* Need custom handler to check the memory failure
* and to take the appropriate next step.
*/
tms570_pbist_fail();
}
} /* end of the code skipped for tms570_running_from_tcram() */
/* Disable PBIST clocks and disable memory self-test mode */
tms570_pbist_stop();
/* Release the MibSPI1 modules from local reset.
* This will cause the MibSPI1 RAMs to get initialized along with the parity memory.
*/
TMS570_SPI1.GCR0 = TMS570_SPI_GCR0_nRESET;
/* Release the MibSPI3 modules from local reset.
* This will cause the MibSPI3 RAMs to get initialized along with the parity memory.
*/
TMS570_SPI3.GCR0 = TMS570_SPI_GCR0_nRESET;
/* Release the MibSPI5 modules from local reset.
* This will cause the MibSPI5 RAMs to get initialized along with the parity memory.
*/
TMS570_SPI5.GCR0 = TMS570_SPI_GCR0_nRESET;
/* Enable parity on selected RAMs */
tms570_enable_parity();
/* Initialize all on-chip SRAMs except for MibSPIx RAMs
* The MibSPIx modules have their own auto-initialization mechanism which is triggered
* as soon as the modules are brought out of local reset.
*/
/* The system module auto-init will hang on the MibSPI RAM if the module is still in local reset.
*/
/* NOTE : Please Refer DEVICE DATASHEET for the list of Supported Memories and their channel numbers.
Memory Initialization is perfomed only on the user selected memories in HALCoGen's GUI SAFETY INIT tab.
*/
tms570_memory_init( (uint32_t) ( (uint32_t) 1U << 1U ) | /* DMA RAM */
(uint32_t) ( (uint32_t) 1U << 2U ) | /* VIM RAM */
(uint32_t) ( (uint32_t) 1U << 5U ) | /* CAN1 RAM */
(uint32_t) ( (uint32_t) 1U << 6U ) | /* CAN2 RAM */
(uint32_t) ( (uint32_t) 1U << 10U ) | /* CAN3 RAM */
(uint32_t) ( (uint32_t) 1U << 8U ) | /* ADC1 RAM */
(uint32_t) ( (uint32_t) 1U << 14U ) | /* ADC2 RAM */
(uint32_t) ( (uint32_t) 1U << 3U ) | /* HET1 RAM */
(uint32_t) ( (uint32_t) 1U << 4U ) | /* HTU1 RAM */
(uint32_t) ( (uint32_t) 1U << 15U ) | /* HET2 RAM */
(uint32_t) ( (uint32_t) 1U << 16U ) /* HTU2 RAM */
);
/* Disable parity */
tms570_disable_parity();
/*
* Test the parity protection mechanism for peripheral RAMs
* Refer DEVICE DATASHEET for the list of Supported Memories
* with parity.
*/
tms570_selftest_par_run( tms570_selftest_par_list,
tms570_selftest_par_list_size );
#if 0
/*
* RTEMS VIM initialization is implemented by the function
* bsp_interrupt_facility_initialize(). RTEMS does not
* gain performance from use of vectors targets provided
* directly by VIM. RTEMS require to route all interrupts
* through _ARMV4_Exception_interrupt handler.
*
* But actual RTEMS VIM initialization lefts some registers
* default values untouched. All registers values should be
* ensured/configured in future probably.
*/
/* Enable IRQ offset via Vic controller */
_coreEnableIrqVicOffset_();
/* Initialize VIM table */
vimInit();
#endif
/* Configure system response to error conditions signaled to the ESM group1 */
tms570_esm_init();
#if 1
/*
* Do not depend on link register to be restored to
* correct value from stack. If TCRAM self test is enabled
* the all stack content is zeroed there.
*/
bsp_start_hook_0_done();
#endif
}
BSP_START_TEXT_SECTION void bsp_start_hook_1( void )
{
/* At this point we can use objects outside the .start section */
#if 0
/* Do not run attempt to initialize MPU when code is running from SDRAM */
if ( !tms570_running_from_sdram() ) {
/*
* MPU background areas setting has to be overlaid
* if execution of code is required from external memory/SDRAM.
* This region is non executable by default.
*/
_mpuInit_();
}
#endif
tms570_emif_sdram_init();
bsp_start_copy_sections();
bsp_start_clear_bss();
}
/*
* Chip specific list of peripherals which should be tested
* for functional RAM parity reporting
*/
const tms570_selftest_par_desc_t *const
tms570_selftest_par_list[] = {
&tms570_selftest_par_het1_desc,
&tms570_selftest_par_htu1_desc,
&tms570_selftest_par_het2_desc,
&tms570_selftest_par_htu2_desc,
&tms570_selftest_par_adc1_desc,
&tms570_selftest_par_adc2_desc,
&tms570_selftest_par_can1_desc,
&tms570_selftest_par_can2_desc,
&tms570_selftest_par_can3_desc,
&tms570_selftest_par_vim_desc,
&tms570_selftest_par_dma_desc,
&tms570_selftest_par_spi1_desc,
&tms570_selftest_par_spi3_desc,
&tms570_selftest_par_spi5_desc,
};
const int tms570_selftest_par_list_size =
RTEMS_ARRAY_SIZE( tms570_selftest_par_list );

View File

@@ -0,0 +1,17 @@
#include <stdint.h>
#include <stdbool.h>
#include <bsp/tms570.h>
#include "tms570_selftest.h"
void bsp_selftest_fail_notification( uint32_t flag )
{
}
void tms570_memory_port0_fail_notification(
uint32_t groupSelect,
uint32_t dataSelect,
uint32_t address,
uint32_t data
)
{
}

View File

@@ -0,0 +1,64 @@
/**
* @file init_emif_sdram.c
*
* @ingroup tms570
*
* @brief Initialization of external memory/SDRAM interface.
*/
#include <stdint.h>
#include <bsp/tms570.h>
#include "tms570_hwinit.h"
void tms570_emif_sdram_init( void )
{
uint32_t dummy;
uint32_t sdtimr = 0;
uint32_t sdcr = 0;
/* Do not run attempt to initialize SDRAM when code is running from it */
if ( ( (void*)tms570_emif_sdram_init >= (void*)TMS570_SDRAM_START_PTR ) &&
( (void*)tms570_emif_sdram_init <= (void*)TMS570_SDRAM_WINDOW_END_PTR ) )
return;
sdtimr = TMS570_EMIF_SDTIMR_T_RFC_SET( sdtimr, 6 - 1 );
sdtimr = TMS570_EMIF_SDTIMR_T_RP_SET( sdtimr, 2 - 1 );
sdtimr = TMS570_EMIF_SDTIMR_T_RCD_SET( sdtimr, 2 - 1 );
sdtimr = TMS570_EMIF_SDTIMR_T_WR_SET( sdtimr, 2 - 1 );
sdtimr = TMS570_EMIF_SDTIMR_T_RAS_SET( sdtimr, 4 - 1 );
sdtimr = TMS570_EMIF_SDTIMR_T_RC_SET( sdtimr, 6 - 1 );
sdtimr = TMS570_EMIF_SDTIMR_T_RRD_SET( sdtimr, 2 - 1 );
TMS570_EMIF.SDTIMR = sdtimr;
/* Minimum number of ECLKOUT cycles from Self-Refresh exit to any command */
TMS570_EMIF.SDSRETR = 5;
/* Define the SDRAM refresh period in terms of EMIF_CLK cycles. */
TMS570_EMIF.SDRCR = 2000;
/* SR - Self-Refresh mode bit. */
sdcr |= TMS570_EMIF_SDCR_SR * 0;
/* field: PD - Power Down bit controls entering and exiting of the power-down mode. */
sdcr |= TMS570_EMIF_SDCR_PD * 0;
/* PDWR - Perform refreshes during power down. */
sdcr |= TMS570_EMIF_SDCR_PDWR * 0;
/* NM - Narrow mode bit defines whether SDRAM is 16- or 32-bit-wide */
sdcr |= TMS570_EMIF_SDCR_NM * 1;
/* CL - CAS Latency. */
sdcr = TMS570_EMIF_SDCR_CL_SET( sdcr, 2 );
/* CL can only be written if BIT11_9LOCK is simultaneously written with a 1. */
sdcr |= TMS570_EMIF_SDCR_BIT11_9LOCK * 1;
/* IBANK - Internal SDRAM Bank size. */
sdcr = TMS570_EMIF_SDCR_IBANK_SET( sdcr, 2 ); /* 4-banks device */
/* Page Size. This field defines the internal page size of connected SDRAM devices. */
sdcr = TMS570_EMIF_SDCR_PAGESIZE_SET( sdcr, 0 ); /* elements_256 */
TMS570_EMIF.SDCR = sdcr;
dummy = *(volatile uint32_t*)TMS570_SDRAM_START_PTR;
(void) dummy;
TMS570_EMIF.SDRCR = 31;
/* Define the SDRAM refresh period in terms of EMIF_CLK cycles. */
TMS570_EMIF.SDRCR = 312;
}

View File

@@ -0,0 +1,62 @@
/**
* @file init_esm.c
*
* @ingroup tms570
*
* @brief Error signaling module initialization
*/
#include <stdint.h>
#include <bsp/tms570.h>
#include "tms570_hwinit.h"
/**
* @brief Error signaling module initialization (HCG:esmInit)
*
*/
void tms570_esm_init( void )
{
/** - Disable error pin channels */
TMS570_ESM.DEPAPR1 = 0xFFFFFFFFU;
TMS570_ESM.IEPCR4 = 0xFFFFFFFFU;
/** - Disable interrupts */
TMS570_ESM.IECR1 = 0xFFFFFFFFU;
TMS570_ESM.IECR4 = 0xFFFFFFFFU;
/** - Clear error status flags */
TMS570_ESM.SR[0U] = 0xFFFFFFFFU;
TMS570_ESM.SR[1U] = 0xFFFFFFFFU;
TMS570_ESM.SSR2 = 0xFFFFFFFFU;
TMS570_ESM.SR[2U] = 0xFFFFFFFFU;
TMS570_ESM.SR4 = 0xFFFFFFFFU;
/** - Setup LPC preload */
TMS570_ESM.LTCPR = 16384U - 1U;
/** - Reset error pin */
if (TMS570_ESM.EPSR == 0U) {
TMS570_ESM.EKR = 0x00000005U;
} else {
TMS570_ESM.EKR = 0x00000000U;
}
/** - Clear interrupt level */
TMS570_ESM.ILCR1 = 0xFFFFFFFFU;
TMS570_ESM.ILCR4 = 0xFFFFFFFFU;
/** - Set interrupt level */
TMS570_ESM.ILSR1 = 0x00000000;
TMS570_ESM.ILSR4 = 0x00000000;
/** - Enable error pin channels */
TMS570_ESM.EEPAPR1 = 0x00000000;
TMS570_ESM.IEPSR4 = 0x00000000;
/** - Enable interrupts */
TMS570_ESM.IESR1 = 0x00000000;
TMS570_ESM.IESR4 = 0x00000000;
}

View File

@@ -0,0 +1,259 @@
/**
* @file init_pinmux.c
*
* @ingroup tms570
*
* @brief Initialize pin multiplexers.
*/
/*
* Copyright (c) 2016 Pavel Pisa <pisa@cmp.felk.cvut.cz>
*
* Czech Technical University in Prague
* Zikova 1903/4
* 166 36 Praha 6
* Czech Republic
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
*/
#include <stdint.h>
#include <bsp/tms570.h>
#include <bsp/tms570-pinmux.h>
#include <rtems.h>
#include "tms570_hwinit.h"
/*
* To check that content is right generated use
*
* objdump --section=.rodata -s init_pinmux.o
*/
#if 0
/*
* Test of use of the default pins configuration with one line added.
* This can be used to concatenate partial lists but care has to
* be taken to not attempt to override already defined pin.
* This would not work and result in two PINMMR bits set
* for given pine.
*/
#ifndef TMS570_PINMMR_INIT_LIST
#define TMS570_PINMMR_INIT_LIST(per_pin_action, common_arg) \
TMS570_PINMMR_DEFAULT_INIT_LIST(per_pin_action, common_arg) \
per_pin_action(common_arg, TMS570_BALL_E3_HET2_18)
#endif
#else
/*
* Definition of fuctions for all pins of TMS570LS3137.
* This setup correctponds to TMS570LS31x HDK Kit
*/
#define TMS570_PINMMR_INIT_LIST( per_pin_action, common_arg ) \
per_pin_action( common_arg, TMS570_BALL_W10_GIOB_3 ) \
per_pin_action( common_arg, TMS570_BALL_A5_GIOA_0 ) \
per_pin_action( common_arg, TMS570_BALL_C3_MIBSPI3NCS_3 ) \
per_pin_action( common_arg, TMS570_BALL_B2_MIBSPI3NCS_2 ) \
per_pin_action( common_arg, TMS570_BALL_C2_GIOA_1 ) \
per_pin_action( common_arg, TMS570_BALL_E3_HET1_11 ) \
per_pin_action( common_arg, TMS570_BALL_E5_EMIF_DATA_4 ) \
per_pin_action( common_arg, TMS570_BALL_F5_EMIF_DATA_5 ) \
per_pin_action( common_arg, TMS570_BALL_C1_GIOA_2 ) \
per_pin_action( common_arg, TMS570_BALL_G5_EMIF_DATA_6 ) \
per_pin_action( common_arg, TMS570_BALL_E1_GIOA_3 ) \
per_pin_action( common_arg, TMS570_BALL_B5_GIOA_5 ) \
per_pin_action( common_arg, TMS570_BALL_K5_EMIF_DATA_7 ) \
per_pin_action( common_arg, TMS570_BALL_B3_HET1_22 ) \
per_pin_action( common_arg, TMS570_BALL_H3_GIOA_6 ) \
per_pin_action( common_arg, TMS570_BALL_L5_EMIF_DATA_8 ) \
per_pin_action( common_arg, TMS570_BALL_M1_GIOA_7 ) \
per_pin_action( common_arg, TMS570_BALL_M5_EMIF_DATA_9 ) \
per_pin_action( common_arg, TMS570_BALL_V2_HET1_01 ) \
per_pin_action( common_arg, TMS570_BALL_U1_HET1_03 ) \
per_pin_action( common_arg, TMS570_BALL_K18_HET1_00 ) \
per_pin_action( common_arg, TMS570_BALL_W5_HET1_02 ) \
per_pin_action( common_arg, TMS570_BALL_V6_HET1_05 ) \
per_pin_action( common_arg, TMS570_BALL_N5_EMIF_DATA_10 ) \
per_pin_action( common_arg, TMS570_BALL_T1_HET1_07 ) \
per_pin_action( common_arg, TMS570_BALL_P5_EMIF_DATA_11 ) \
per_pin_action( common_arg, TMS570_BALL_V7_HET1_09 ) \
per_pin_action( common_arg, TMS570_BALL_R5_EMIF_DATA_12 ) \
per_pin_action( common_arg, TMS570_BALL_R6_EMIF_DATA_13 ) \
per_pin_action( common_arg, TMS570_BALL_V5_MIBSPI3NCS_1 ) \
per_pin_action( common_arg, TMS570_BALL_W3_SCIRX ) \
per_pin_action( common_arg, TMS570_BALL_R7_EMIF_DATA_14 ) \
per_pin_action( common_arg, TMS570_BALL_N2_SCITX ) \
per_pin_action( common_arg, TMS570_BALL_G3_MIBSPI1NCS_2 ) \
per_pin_action( common_arg, TMS570_BALL_N1_HET1_15 ) \
per_pin_action( common_arg, TMS570_BALL_R8_EMIF_DATA_15 ) \
per_pin_action( common_arg, TMS570_BALL_R9_ETMTRACECLKIN ) \
per_pin_action( common_arg, TMS570_BALL_W9_MIBSPI3NENA ) \
per_pin_action( common_arg, TMS570_BALL_V10_MIBSPI3NCS_0 ) \
per_pin_action( common_arg, TMS570_BALL_J3_MIBSPI1NCS_3 ) \
per_pin_action( common_arg, TMS570_BALL_N19_AD1EVT ) \
per_pin_action( common_arg, TMS570_BALL_N15_EMIF_DATA_3 ) \
per_pin_action( common_arg, TMS570_BALL_N17_EMIF_nCS_0 ) \
per_pin_action( common_arg, TMS570_BALL_M15_EMIF_DATA_2 ) \
per_pin_action( common_arg, TMS570_BALL_K17_EMIF_nCS_3 ) \
per_pin_action( common_arg, TMS570_BALL_M17_EMIF_nCS_4 ) \
per_pin_action( common_arg, TMS570_BALL_L15_EMIF_DATA_1 ) \
per_pin_action( common_arg, TMS570_BALL_P1_HET1_24 ) \
per_pin_action( common_arg, TMS570_BALL_A14_HET1_26 ) \
per_pin_action( common_arg, TMS570_BALL_K15_EMIF_DATA_0 ) \
per_pin_action( common_arg, TMS570_BALL_G19_MIBSPI1NENA ) \
per_pin_action( common_arg, TMS570_BALL_H18_MIBSPI5NENA ) \
per_pin_action( common_arg, TMS570_BALL_J18_MIBSPI5SOMI_0 ) \
per_pin_action( common_arg, TMS570_BALL_J19_MIBSPI5SIMO_0 ) \
per_pin_action( common_arg, TMS570_BALL_H19_MIBSPI5CLK ) \
per_pin_action( common_arg, TMS570_BALL_R2_MIBSPI1NCS_0 ) \
per_pin_action( common_arg, TMS570_BALL_E18_HET1_08 ) \
per_pin_action( common_arg, TMS570_BALL_K19_HET1_28 ) \
per_pin_action( common_arg, TMS570_BALL_D17_EMIF_nWE ) \
per_pin_action( common_arg, TMS570_BALL_D16_EMIF_BA_1 ) \
per_pin_action( common_arg, TMS570_BALL_C17_EMIF_ADDR_21 ) \
per_pin_action( common_arg, TMS570_BALL_C16_EMIF_ADDR_20 ) \
per_pin_action( common_arg, TMS570_BALL_C15_EMIF_ADDR_19 ) \
per_pin_action( common_arg, TMS570_BALL_D15_EMIF_ADDR_18 ) \
per_pin_action( common_arg, TMS570_BALL_E13_EMIF_BA_0 ) \
per_pin_action( common_arg, TMS570_BALL_C14_EMIF_ADDR_17 ) \
per_pin_action( common_arg, TMS570_BALL_D14_EMIF_ADDR_16 ) \
per_pin_action( common_arg, TMS570_BALL_E12_EMIF_nOE ) \
per_pin_action( common_arg, TMS570_BALL_D19_HET1_10 ) \
per_pin_action( common_arg, TMS570_BALL_E11_EMIF_nDQM_1 ) \
per_pin_action( common_arg, TMS570_BALL_B4_HET1_12 ) \
per_pin_action( common_arg, TMS570_BALL_E9_EMIF_ADDR_5 ) \
per_pin_action( common_arg, TMS570_BALL_C13_EMIF_ADDR_15 ) \
per_pin_action( common_arg, TMS570_BALL_A11_HET1_14 ) \
per_pin_action( common_arg, TMS570_BALL_C12_EMIF_ADDR_14 ) \
per_pin_action( common_arg, TMS570_BALL_M2_GIOB_0 ) \
per_pin_action( common_arg, TMS570_BALL_E8_EMIF_ADDR_4 ) \
per_pin_action( common_arg, TMS570_BALL_B11_HET1_30 ) \
per_pin_action( common_arg, TMS570_BALL_E10_EMIF_nDQM_0 ) \
per_pin_action( common_arg, TMS570_BALL_E7_EMIF_ADDR_3 ) \
per_pin_action( common_arg, TMS570_BALL_C11_EMIF_ADDR_13 ) \
per_pin_action( common_arg, TMS570_BALL_C10_EMIF_ADDR_12 ) \
per_pin_action( common_arg, TMS570_BALL_F3_MIBSPI1NCS_1 ) \
per_pin_action( common_arg, TMS570_BALL_C9_EMIF_ADDR_11 ) \
per_pin_action( common_arg, TMS570_BALL_D5_EMIF_ADDR_1 ) \
per_pin_action( common_arg, TMS570_BALL_K2_GIOB_1 ) \
per_pin_action( common_arg, TMS570_BALL_C8_EMIF_ADDR_10 ) \
per_pin_action( common_arg, TMS570_BALL_C7_EMIF_ADDR_9 ) \
per_pin_action( common_arg, TMS570_BALL_D4_EMIF_ADDR_0 ) \
per_pin_action( common_arg, TMS570_BALL_C5_EMIF_ADDR_7 ) \
per_pin_action( common_arg, TMS570_BALL_C4_EMIF_ADDR_6 ) \
per_pin_action( common_arg, TMS570_BALL_E6_EMIF_ADDR_2 ) \
per_pin_action( common_arg, TMS570_BALL_C6_EMIF_ADDR_8 ) \
per_pin_action( common_arg, TMS570_MMR_SELECT_SPI4CLK ) \
per_pin_action( common_arg, TMS570_MMR_SELECT_SPI4SIMO ) \
per_pin_action( common_arg, TMS570_MMR_SELECT_SPI4SOMI ) \
per_pin_action( common_arg, TMS570_MMR_SELECT_SPI4NENA ) \
per_pin_action( common_arg, TMS570_MMR_SELECT_SPI4NCS_0 ) \
per_pin_action( common_arg, TMS570_BALL_A13_HET1_17 ) \
per_pin_action( common_arg, TMS570_BALL_B13_HET1_19 ) \
per_pin_action( common_arg, TMS570_BALL_H4_HET1_21 ) \
per_pin_action( common_arg, TMS570_BALL_J4_HET1_23 ) \
per_pin_action( common_arg, TMS570_BALL_M3_HET1_25 ) \
per_pin_action( common_arg, TMS570_BALL_A9_HET1_27 ) \
per_pin_action( common_arg, TMS570_BALL_A3_HET1_29 ) \
per_pin_action( common_arg, TMS570_BALL_J17_HET1_31 ) \
per_pin_action( common_arg, TMS570_BALL_W6_MIBSPI5NCS_2 ) \
per_pin_action( common_arg, TMS570_BALL_T12_MIBSPI5NCS_3 ) \
per_pin_action( common_arg, TMS570_BALL_E19_MIBSPI5NCS_0 ) \
per_pin_action( common_arg, TMS570_BALL_B6_MIBSPI5NCS_1 ) \
per_pin_action( common_arg, TMS570_BALL_E16_MIBSPI5SIMO_1 ) \
per_pin_action( common_arg, TMS570_BALL_H17_MIBSPI5SIMO_2 ) \
per_pin_action( common_arg, TMS570_BALL_G17_MIBSPI5SIMO_3 ) \
per_pin_action( common_arg, TMS570_BALL_E17_MIBSPI5SOMI_1 ) \
per_pin_action( common_arg, TMS570_BALL_H16_MIBSPI5SOMI_2 ) \
per_pin_action( common_arg, TMS570_BALL_G16_MIBSPI5SOMI_3 ) \
per_pin_action( common_arg, TMS570_BALL_D3_SPI2NENA ) \
per_pin_action( common_arg, \
TMS570_MMR_SELECT_EMIF_CLK_SEL | TMS570_PIN_CLEAR_RQ_MASK ) \
per_pin_action( common_arg, \
TMS570_BALL_F2_GIOB_2 | TMS570_PIN_CLEAR_RQ_MASK ) \
per_pin_action( common_arg, \
TMS570_MMR_SELECT_GMII_SEL | TMS570_PIN_CLEAR_RQ_MASK ) \
per_pin_action( common_arg, TMS570_MMR_SELECT_ADC_TRG1 ) \
#endif
/*
* The next construct allows to compute values for individual
* PINMMR registers based on the multiple processing
* complete pin functions list at compile time.
* Each line computes 32-bit value which selects function
* of consecutive four pins. Each pin function is defined
* by single byte.
*/
const uint32_t tms570_pinmmr_init_data[] = {
TMS570_PINMMR_REG_VAL( 0, TMS570_PINMMR_INIT_LIST ),
TMS570_PINMMR_REG_VAL( 1, TMS570_PINMMR_INIT_LIST ),
TMS570_PINMMR_REG_VAL( 2, TMS570_PINMMR_INIT_LIST ),
TMS570_PINMMR_REG_VAL( 3, TMS570_PINMMR_INIT_LIST ),
TMS570_PINMMR_REG_VAL( 4, TMS570_PINMMR_INIT_LIST ),
TMS570_PINMMR_REG_VAL( 5, TMS570_PINMMR_INIT_LIST ),
TMS570_PINMMR_REG_VAL( 6, TMS570_PINMMR_INIT_LIST ),
TMS570_PINMMR_REG_VAL( 7, TMS570_PINMMR_INIT_LIST ),
TMS570_PINMMR_REG_VAL( 8, TMS570_PINMMR_INIT_LIST ),
TMS570_PINMMR_REG_VAL( 9, TMS570_PINMMR_INIT_LIST ),
TMS570_PINMMR_REG_VAL( 10, TMS570_PINMMR_INIT_LIST ),
TMS570_PINMMR_REG_VAL( 11, TMS570_PINMMR_INIT_LIST ),
TMS570_PINMMR_REG_VAL( 12, TMS570_PINMMR_INIT_LIST ),
TMS570_PINMMR_REG_VAL( 13, TMS570_PINMMR_INIT_LIST ),
TMS570_PINMMR_REG_VAL( 14, TMS570_PINMMR_INIT_LIST ),
TMS570_PINMMR_REG_VAL( 15, TMS570_PINMMR_INIT_LIST ),
TMS570_PINMMR_REG_VAL( 16, TMS570_PINMMR_INIT_LIST ),
TMS570_PINMMR_REG_VAL( 17, TMS570_PINMMR_INIT_LIST ),
TMS570_PINMMR_REG_VAL( 18, TMS570_PINMMR_INIT_LIST ),
TMS570_PINMMR_REG_VAL( 19, TMS570_PINMMR_INIT_LIST ),
TMS570_PINMMR_REG_VAL( 20, TMS570_PINMMR_INIT_LIST ),
TMS570_PINMMR_REG_VAL( 21, TMS570_PINMMR_INIT_LIST ),
TMS570_PINMMR_REG_VAL( 22, TMS570_PINMMR_INIT_LIST ),
TMS570_PINMMR_REG_VAL( 23, TMS570_PINMMR_INIT_LIST ),
TMS570_PINMMR_REG_VAL( 24, TMS570_PINMMR_INIT_LIST ),
TMS570_PINMMR_REG_VAL( 25, TMS570_PINMMR_INIT_LIST ),
TMS570_PINMMR_REG_VAL( 26, TMS570_PINMMR_INIT_LIST ),
TMS570_PINMMR_REG_VAL( 27, TMS570_PINMMR_INIT_LIST ),
TMS570_PINMMR_REG_VAL( 28, TMS570_PINMMR_INIT_LIST ),
TMS570_PINMMR_REG_VAL( 29, TMS570_PINMMR_INIT_LIST ),
TMS570_PINMMR_REG_VAL( 30, TMS570_PINMMR_INIT_LIST ),
};
/**
* @brief setups pin multiplexer according to precomputed registers values (HCG:muxInit)
*/
void tms570_pinmux_init( void )
{
tms570_bsp_pinmmr_config( tms570_pinmmr_init_data, 0,
RTEMS_ARRAY_SIZE( tms570_pinmmr_init_data ) );
}
#if 0
/*
* Alternative option how to set function of individual pins
* or use list for one by one setting. This is much slower
* and consumes more memory to hold complete list.
*
* On the other hand this solution can be used for configuration
* or reconfiguration of some shorter groups of pins at runtime.
*
*/
const uint32_t tms570_pinmmr_init_list[] = {
TMS570_PINMMR_COMA_LIST( TMS570_PINMMR_INIT_LIST )
};
void tms570_pinmux_init_by_list( void )
{
int pincnt = RTEMS_ARRAY_SIZE( tms570_pinmmr_init_list );
const uint32_t *pinfnc = tms570_pinmmr_init_list;
while ( pincnt-- )
tms570_bsp_pin_config_one( *(pinfnc++) );
}
#endif

View File

@@ -0,0 +1,378 @@
/** @file init_system.c
based on Ti HalCoGen generated file
*/
/*
* Copyright (C) 2009-2015 Texas Instruments Incorporated - 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 <bsp/tms570.h>
#include <bsp/tms570-pinmux.h>
#include "tms570_selftest.h"
#include "tms570_hwinit.h"
/**
* @brief Setup all system PLLs (HCG:setupPLL)
*
*/
void tms570_pll_init( void )
{
uint32_t pll12_dis = 0x42;
/* Disable PLL1 and PLL2 */
TMS570_SYS1.CSDISSET = pll12_dis;
/*SAFETYMCUSW 28 D MR:NA <APPROVED> "Hardware status bit read check" */
while ( ( TMS570_SYS1.CSDIS & pll12_dis ) != pll12_dis ) {
/* Wait */
}
/* Clear Global Status Register */
TMS570_SYS1.GLBSTAT = TMS570_SYS1_GLBSTAT_FBSLIP |
TMS570_SYS1_GLBSTAT_RFSLIP |
TMS570_SYS1_GLBSTAT_OSCFAIL;
/** - Configure PLL control registers */
/** @b Initialize @b Pll1: */
/* Setup pll control register 1 */
TMS570_SYS1.PLLCTL1 = TMS570_SYS1_PLLCTL1_ROS * 0 |
TMS570_SYS1_PLLCTL1_MASK_SLIP( 1 ) |
TMS570_SYS1_PLLCTL1_PLLDIV( 0x1f ) | /* max value */
TMS570_SYS1_PLLCTL1_ROF * 0 |
TMS570_SYS1_PLLCTL1_REFCLKDIV( 6 - 1 ) |
TMS570_SYS1_PLLCTL1_PLLMUL( ( 120 - 1 ) << 8 );
/* Setup pll control register 2 */
TMS570_SYS1.PLLCTL2 = TMS570_SYS1_PLLCTL2_FMENA * 0 |
TMS570_SYS1_PLLCTL2_SPREADINGRATE( 255 ) |
TMS570_SYS1_PLLCTL2_MULMOD( 7 ) |
TMS570_SYS1_PLLCTL2_ODPLL( 2 - 1 ) |
TMS570_SYS1_PLLCTL2_SPR_AMOUNT( 61 );
/** @b Initialize @b Pll2: */
/* Setup pll2 control register */
TMS570_SYS2.PLLCTL3 = TMS570_SYS2_PLLCTL3_ODPLL2( 2 - 1 ) |
TMS570_SYS2_PLLCTL3_PLLDIV2( 0x1F ) | /* max value */
TMS570_SYS2_PLLCTL3_REFCLKDIV2( 6 - 1 ) |
TMS570_SYS2_PLLCTL3_PLLMUL2( ( 120 - 1 ) << 8 );
/** - Enable PLL(s) to start up or Lock */
TMS570_SYS1.CSDIS = 0x00000000 | /* CLKSR0 on */
0x00000000 | /* CLKSR1 on */
0x00000008 | /* CLKSR3 off */
0x00000000 | /* CLKSR4 on */
0x00000000 | /* CLKSR5 on */
0x00000000 | /* CLKSR6 on */
0x00000080; /* CLKSR7 off */
}
/**
* @brief Adjust Low-Frequency (LPO) oscilator (HCG:trimLPO)
*
*/
/* SourceId : SYSTEM_SourceId_002 */
/* DesignId : SYSTEM_DesignId_002 */
/* Requirements : HL_SR468 */
void tms570_trim_lpo_init( void )
{
/** @b Initialize Lpo: */
/** Load TRIM values from OTP if present else load user defined values */
/*SAFETYMCUSW 139 S MR:13.7 <APPROVED> "Hardware status bit read check" */
TMS570_SYS1.LPOMONCTL = TMS570_SYS1_LPOMONCTL_BIAS_ENABLE |
TMS570_SYS1_LPOMONCTL_OSCFRQCONFIGCNT * 0 |
TMS570_SYS1_LPOMONCTL_HFTRIM( 16 ) |
16; /* LFTRIM */
}
/* FIXME */
enum tms570_flash_power_modes {
TMS570_FLASH_SYS_SLEEP = 0U, /**< Alias for flash bank power mode sleep */
TMS570_FLASH_SYS_STANDBY = 1U, /**< Alias for flash bank power mode standby */
TMS570_FLASH_SYS_ACTIVE = 3U /**< Alias for flash bank power mode active */
};
enum tms570_system_clock_source {
TMS570_SYS_CLK_SRC_OSC = 0U, /**< Alias for oscillator clock Source */
TMS570_SYS_CLK_SRC_PLL1 = 1U, /**< Alias for Pll1 clock Source */
TMS570_SYS_CLK_SRC_EXTERNAL1 = 3U, /**< Alias for external clock Source */
TMS570_SYS_CLK_SRC_LPO_LOW = 4U, /**< Alias for low power oscillator low clock Source */
TMS570_SYS_CLK_SRC_LPO_HIGH = 5U, /**< Alias for low power oscillator high clock Source */
TMS570_SYS_CLK_SRC_PLL2 = 6U, /**< Alias for Pll2 clock Source */
TMS570_SYS_CLK_SRC_EXTERNAL2 = 7U, /**< Alias for external 2 clock Source */
TMS570_SYS_CLK_SRC_VCLK = 9U /**< Alias for synchronous VCLK1 clock Source */
};
/**
* @brief Setup Flash memory parameters and timing (HCG:setupFlash)
*
*/
/* SourceId : SYSTEM_SourceId_003 */
/* DesignId : SYSTEM_DesignId_003 */
/* Requirements : HL_SR457 */
void tms570_flash_init( void )
{
/** - Setup flash read mode, address wait states and data wait states */
TMS570_FLASH.FRDCNTL = TMS570_FLASH_FRDCNTL_RWAIT( 3 ) |
TMS570_FLASH_FRDCNTL_ASWSTEN |
TMS570_FLASH_FRDCNTL_ENPIPE;
/** - Setup flash access wait states for bank 7 */
TMS570_FLASH.FSMWRENA = TMS570_FLASH_FSMWRENA_WR_ENA( 0x5 );
TMS570_FLASH.EEPROMCONFIG = TMS570_FLASH_EEPROMCONFIG_EWAIT( 3 ) |
TMS570_FLASH_EEPROMCONFIG_AUTOSUSP_EN * 0 |
TMS570_FLASH_EEPROMCONFIG_AUTOSTART_GRACE( 2 );
/** - Disable write access to flash state machine registers */
TMS570_FLASH.FSMWRENA = TMS570_FLASH_FSMWRENA_WR_ENA( 0xA );
/** - Setup flash bank power modes */
TMS570_FLASH.FBFALLBACK = TMS570_FLASH_FBFALLBACK_BANKPWR7(
TMS570_FLASH_SYS_ACTIVE ) |
TMS570_FLASH_FBFALLBACK_BANKPWR1(
TMS570_FLASH_SYS_ACTIVE ) |
TMS570_FLASH_FBFALLBACK_BANKPWR0(
TMS570_FLASH_SYS_ACTIVE );
}
/**
* @brief Power-up all peripherals and enable their clocks (HCG:periphInit)
*
*/
/* SourceId : SYSTEM_SourceId_004 */
/* DesignId : SYSTEM_DesignId_004 */
/* Requirements : HL_SR470 */
void tms570_periph_init( void )
{
/** - Disable Peripherals before peripheral powerup*/
TMS570_SYS1.CLKCNTL &= ~TMS570_SYS1_CLKCNTL_PENA;
/** - Release peripherals from reset and enable clocks to all peripherals */
/** - Power-up all peripherals */
TMS570_PCR.PSPWRDWNCLR0 = 0xFFFFFFFFU;
TMS570_PCR.PSPWRDWNCLR1 = 0xFFFFFFFFU;
TMS570_PCR.PSPWRDWNCLR2 = 0xFFFFFFFFU;
TMS570_PCR.PSPWRDWNCLR3 = 0xFFFFFFFFU;
/** - Enable Peripherals */
TMS570_SYS1.CLKCNTL |= TMS570_SYS1_CLKCNTL_PENA;
}
/**
* @brief Setup chip clocks including to wait for PLLs locks (HCG:mapClocks)
*
*/
/* SourceId : SYSTEM_SourceId_005 */
/* DesignId : SYSTEM_DesignId_005 */
/* Requirements : HL_SR469 */
void tms570_map_clock_init( void )
{
uint32_t sys_csvstat, sys_csdis;
/** @b Initialize @b Clock @b Tree: */
/** - Disable / Enable clock domain */
TMS570_SYS1.CDDIS = ( 0U << 4U ) | /* AVCLK 1 OFF */
( 0U << 5U ) | /* AVCLK 2 OFF */
( 0U << 8U ) | /* VCLK3 OFF */
( 0U << 9U ) | /* VCLK4 OFF */
( 1U << 10U ) | /* AVCLK 3 OFF */
( 0U << 11U ); /* AVCLK 4 OFF */
/* Work Around for Errata SYS#46:
*
* Errata Description:
* Clock Source Switching Not Qualified with Clock Source Enable And Clock Source Valid
* Workaround:
* Always check the CSDIS register to make sure the clock source is turned on and check
* the CSVSTAT register to make sure the clock source is valid. Then write to GHVSRC to switch the clock.
*/
/** - Wait for until clocks are locked */
sys_csvstat = TMS570_SYS1.CSVSTAT;
sys_csdis = TMS570_SYS1.CSDIS;
while ( ( sys_csvstat & ( ( sys_csdis ^ 0xFFU ) & 0xFFU ) ) !=
( ( sys_csdis ^ 0xFFU ) & 0xFFU ) ) {
sys_csvstat = TMS570_SYS1.CSVSTAT;
sys_csdis = TMS570_SYS1.CSDIS;
} /* Wait */
/* Now the PLLs are locked and the PLL outputs can be sped up */
/* The R-divider was programmed to be 0xF. Now this divider is changed to programmed value */
TMS570_SYS1.PLLCTL1 =
( TMS570_SYS1.PLLCTL1 & ~TMS570_SYS1_PLLCTL1_PLLDIV( 0x1F ) ) |
TMS570_SYS1_PLLCTL1_PLLDIV( 1 - 1 );
/*SAFETYMCUSW 134 S MR:12.2 <APPROVED> "LDRA Tool issue" */
TMS570_SYS2.PLLCTL3 =
( TMS570_SYS2.PLLCTL3 & ~TMS570_SYS2_PLLCTL3_PLLDIV2( 0x1F ) ) |
TMS570_SYS2_PLLCTL3_PLLDIV2( 1 - 1 );
/* Enable/Disable Frequency modulation */
TMS570_SYS1.PLLCTL2 &= ~TMS570_SYS1_PLLCTL2_FMENA;
/** - Map device clock domains to desired sources and configure top-level dividers */
/** - All clock domains are working off the default clock sources until now */
/** - The below assignments can be easily modified using the HALCoGen GUI */
/** - Setup GCLK, HCLK and VCLK clock source for normal operation, power down mode and after wakeup */
TMS570_SYS1.GHVSRC = TMS570_SYS1_GHVSRC_GHVWAKE( TMS570_SYS_CLK_SRC_OSC ) |
TMS570_SYS1_GHVSRC_HVLPM( TMS570_SYS_CLK_SRC_OSC ) |
TMS570_SYS1_GHVSRC_GHVSRC( TMS570_SYS_CLK_SRC_PLL1 );
/** - Setup synchronous peripheral clock dividers for VCLK1, VCLK2, VCLK3 */
TMS570_SYS1.CLKCNTL =
( TMS570_SYS1.CLKCNTL & ~TMS570_SYS1_CLKCNTL_VCLK2R( 0xF ) ) |
TMS570_SYS1_CLKCNTL_VCLK2R( 1 );
TMS570_SYS1.CLKCNTL =
( TMS570_SYS1.CLKCNTL & ~TMS570_SYS1_CLKCNTL_VCLKR( 0xF ) ) |
TMS570_SYS1_CLKCNTL_VCLKR( 1 );
TMS570_SYS2.CLK2CNTRL =
( TMS570_SYS2.CLK2CNTRL & ~TMS570_SYS2_CLK2CNTRL_VCLK3R( 0xF ) ) |
TMS570_SYS2_CLK2CNTRL_VCLK3R( 1 );
TMS570_SYS2.CLK2CNTRL = ( TMS570_SYS2.CLK2CNTRL & 0xFFFFF0FFU ) |
( 1U << 8U ); /* FIXME: unknown in manual*/
/** - Setup RTICLK1 and RTICLK2 clocks */
TMS570_SYS1.RCLKSRC = ( 1U << 24U ) |
( TMS570_SYS_CLK_SRC_VCLK << 16U ) | /* FIXME: not in manual */
TMS570_SYS1_RCLKSRC_RTI1DIV( 1 ) |
TMS570_SYS1_RCLKSRC_RTI1SRC( TMS570_SYS_CLK_SRC_VCLK );
/** - Setup asynchronous peripheral clock sources for AVCLK1 and AVCLK2 */
TMS570_SYS1.VCLKASRC =
TMS570_SYS1_VCLKASRC_VCLKA2S( TMS570_SYS_CLK_SRC_VCLK ) |
TMS570_SYS1_VCLKASRC_VCLKA1S( TMS570_SYS_CLK_SRC_VCLK );
TMS570_SYS2.VCLKACON1 = TMS570_SYS2_VCLKACON1_VCLKA4R( 1 - 1 ) |
TMS570_SYS2_VCLKACON1_VCLKA4_DIV_CDDIS * 0 |
TMS570_SYS2_VCLKACON1_VCLKA4S(
TMS570_SYS_CLK_SRC_VCLK ) |
TMS570_SYS2_VCLKACON1_VCLKA3R( 1 - 1 ) |
TMS570_SYS2_VCLKACON1_VCLKA3_DIV_CDDIS * 0 |
TMS570_SYS2_VCLKACON1_VCLKA3S(
TMS570_SYS_CLK_SRC_VCLK );
}
/**
* @brief TMS570 system hardware initialization (HCG:systemInit)
*
*/
/* SourceId : SYSTEM_SourceId_006 */
/* DesignId : SYSTEM_DesignId_006 */
/* Requirements : HL_SR471 */
void tms570_system_hw_init( void )
{
uint32_t efc_check_status;
/* Configure PLL control registers and enable PLLs.
* The PLL takes (127 + 1024 * NR) oscillator cycles to acquire lock.
* This initialization sequence performs all the tasks that are not
* required to be done at full application speed while the PLL locks.
*/
tms570_pll_init();
/* Run eFuse controller start-up checks and start eFuse controller ECC self-test.
* This includes a check for the eFuse controller error outputs to be stuck-at-zero.
*/
efc_check_status = tms570_efc_check();
/* Enable clocks to peripherals and release peripheral reset */
tms570_periph_init();
/* Configure device-level multiplexing and I/O multiplexing */
tms570_pinmux_init();
/* Enable external memory interface */
TMS570_SYS1.GPREG1 |= TMS570_SYS1_GPREG1_EMIF_FUNC;
if ( efc_check_status == 0U ) {
/* Wait for eFuse controller self-test to complete and check results */
if ( tms570_efc_check_self_test() == false ) { /* eFuse controller ECC logic self-test failed */
bsp_selftest_fail_notification( EFCCHECK_FAIL1 ); /* device operation is not reliable */
}
} else if ( efc_check_status == 2U ) {
/* Wait for eFuse controller self-test to complete and check results */
if ( tms570_efc_check_self_test() == false ) { /* eFuse controller ECC logic self-test failed */
bsp_selftest_fail_notification( EFCCHECK_FAIL1 ); /* device operation is not reliable */
} else {
bsp_selftest_fail_notification( EFCCHECK_FAIL2 );
}
} else {
/* Empty */
}
/** - Set up flash address and data wait states based on the target CPU clock frequency
* The number of address and data wait states for the target CPU clock frequency are specified
* in the specific part's datasheet.
*/
tms570_flash_init();
/** - Configure the LPO such that HF LPO is as close to 10MHz as possible */
tms570_trim_lpo_init();
/** - Wait for PLLs to start up and map clock domains to desired clock sources */
tms570_map_clock_init();
/** - set ECLK pins functional mode */
TMS570_SYS1.SYSPC1 = 0U;
/** - set ECLK pins default output value */
TMS570_SYS1.SYSPC4 = 0U;
/** - set ECLK pins output direction */
TMS570_SYS1.SYSPC2 = 1U;
/** - set ECLK pins open drain enable */
TMS570_SYS1.SYSPC7 = 0U;
/** - set ECLK pins pullup/pulldown enable */
TMS570_SYS1.SYSPC8 = 0U;
/** - set ECLK pins pullup/pulldown select */
TMS570_SYS1.SYSPC9 = 1U;
/** - Setup ECLK */
TMS570_SYS1.ECPCNTL = TMS570_SYS1_ECPCNTL_ECPSSEL * 0 |
TMS570_SYS1_ECPCNTL_ECPCOS * 0 |
TMS570_SYS1_ECPCNTL_ECPDIV( 8 - 1 );
}
#if 0
errata_PBIST_4
vimInit
#endif

View File

@@ -0,0 +1,31 @@
#ifndef LIBBSP_ARM_TMS570_HWINIT_H
#define LIBBSP_ARM_TMS570_HWINIT_H
#define TMS570_TCRAM_START_PTR ( (void *) ( 0x08000000U ) )
#define TMS570_TCRAM_WINDOW_END_PTR ( (void *) ( 0x08080000U ) )
#define TMS570_SDRAM_START_PTR ( (void *) ( 0x80000000U ) )
#define TMS570_SDRAM_WINDOW_END_PTR ( (void *) ( 0xA0000000U ) )
/* Ti TMS570 core setup implemented in assembly */
void _esmCcmErrorsClear_( void );
void _coreEnableEventBusExport_( void );
void _errata_CORTEXR4_66_( void );
void _errata_CORTEXR4_57_( void );
void _coreEnableRamEcc_( void );
void _coreDisableRamEcc_( void );
void _mpuInit_( void );
void tms570_emif_sdram_init( void );
void tms570_memory_init( uint32_t ram );
void tms570_system_hw_init( void );
void tms570_pinmux_init( void );
void tms570_pll_init( void );
void tms570_trim_lpo_init( void );
void tms570_flash_init( void );
void tms570_periph_init( void );
void tms570_map_clock_init( void );
void tms570_system_hw_init( void );
void tms570_esm_init( void );
#endif /* LIBBSP_ARM_TMS570_HWINIT_H */

View File

@@ -0,0 +1,598 @@
/**
* @file tms570_selftest.c
*
* @ingroup tms570
*
* @brief TMS570 selftest support functions implementation.
*/
/*
* Copyright (C) 2009-2015 Texas Instruments Incorporated - 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 <stddef.h>
#include <bsp/tms570.h>
#include "tms570_selftest.h"
#include "tms570_hwinit.h"
/**
* @brief Checks to see if the EFUSE Stuck at zero test is completed successfully (HCG:efcStuckZeroTest).
/
* @return 1 if EFUSE Stuck at zero test completed, otherwise 0.
*
* Checks to see if the EFUSE Stuck at zero test is completed successfully.
*/
/* SourceId : SELFTEST_SourceId_012 */
/* DesignId : SELFTEST_DesignId_014 */
/* Requirements : HL_SR402 */
bool tms570_efc_stuck_zero( void )
{
uint32_t esm_estatus4, esm_estatus1;
bool result = false;
uint32_t output_enable = TMS570_EFUSE_EFCBOUND_Self_Test_Error_OE |
TMS570_EFUSE_EFCBOUND_Single_Bit_Error_OE |
TMS570_EFUSE_EFCBOUND_Instruction_Error_OE |
TMS570_EFUSE_EFCBOUND_Autoload_Error_OE;
uint32_t error_checks = TMS570_EFUSE_EFCBOUND_EFC_Single_Bit_Error |
TMS570_EFUSE_EFCBOUND_EFC_Instruction_Error |
TMS570_EFUSE_EFCBOUND_EFC_Autoload_Error |
TMS570_EFUSE_EFCBOUND_EFC_Self_Test_Error;
/* configure the output enable for auto load error , instruction info,
instruction error, and self test error using boundary register
and drive values one across all the errors */
TMS570_EFUSE.EFCBOUND = output_enable | error_checks;
/* Read from the pin register. This register holds the current values
of above errors. This value should be 0x5c00.If not at least one of
the above errors is stuck at 0. */
if ( ( TMS570_EFUSE.EFCPINS & 0x5C00U ) == 0x5C00U ) {
esm_estatus4 = TMS570_ESM.SR4;
esm_estatus1 = TMS570_ESM.SR[ 2U ];
/* check if the ESM group1 channel 41 is set and group3 channel 1 is set */
if ( ( ( esm_estatus4 & 0x200U ) == 0x200U ) &&
( ( esm_estatus1 & 0x2U ) == 0x2U ) ) {
/* stuck-at-zero test passed */
result = true;
}
}
/* put the pins back low */
TMS570_EFUSE.EFCBOUND = output_enable;
/* clear group1 flag */
TMS570_ESM.SR4 = 0x200U;
/* clear group3 flag */
TMS570_ESM.SR[ 2U ] = 0x2U;
/* The nERROR pin will become inactive once the LTC counter expires */
TMS570_ESM.EKR = 0x5U;
return result;
}
/**
* @brief EFUSE module self check Driver (HCG:efcSelfTest)
*
* This function self checks the EFSUE module.
*/
/* SourceId : SELFTEST_SourceId_013 */
/* DesignId : SELFTEST_DesignId_013 */
/* Requirements : HL_SR402 */
void tms570_efc_self_test( void )
{
/* configure self-test cycles */
TMS570_EFUSE.EFC_ST_CY = 0x258U;
/* configure self-test signature */
TMS570_EFUSE.EFC_ST_SIG = 0x5362F97FU;
/* configure boundary register to start ECC self-test */
TMS570_EFUSE.EFCBOUND = 0x00002000 |
TMS570_EFUSE_EFCBOUND_Input_Enable( 0xF );
}
/**
* @brief EFUSE module self check Driver (HCG:checkefcSelfTest)
*
* @return Returns TRUE if EFC Selftest was a PASS, else FALSE
*
* This function returns the status of efcSelfTest.
* Note: This function can be called only after calling efcSelfTest
*/
/* SourceId : SELFTEST_SourceId_014 */
/* DesignId : SELFTEST_DesignId_015 */
/* Requirements : HL_SR403 */
bool tms570_efc_check_self_test( void )
{
bool result = false;
uint32_t efc_pins, efc_error;
uint32_t esmCh40Stat, esmCh41Stat = 0U;
/* wait until EFC self-test is done */
/*SAFETYMCUSW 28 D MR:NA <APPROVED> "Hardware status bit read check" */
while ( ( TMS570_EFUSE.EFCPINS & TMS570_EFUSE_EFCPINS_EFC_Selftest_Done ) ==
0U ) {
} /* Wait */
/* check if EFC self-test error occurred */
efc_pins = TMS570_EFUSE.EFCPINS;
efc_error = TMS570_EFUSE.EFC_ERR_STAT;
if ( ( ( efc_pins & TMS570_EFUSE_EFCPINS_EFC_Selftest_Error ) == 0U ) &&
( ( efc_error & 0x1FU ) == 0U ) ) {
/* check if EFC self-test error is set */
esmCh40Stat = TMS570_ESM.SR4 & 0x100U;
esmCh41Stat = TMS570_ESM.SR4 & 0x200U;
if ( ( esmCh40Stat == 0U ) && ( esmCh41Stat == 0U ) ) {
result = true;
}
}
return result;
}
/**
* @brief EFUSE module self check Driver (HCG:efcCheck)
* @return Returns 0 if no error was detected during autoload and Stuck At Zero Test passed
* 1 if no error was detected during autoload but Stuck At Zero Test failed
* 2 if there was a single-bit error detected during autoload
* 3 if some other error occurred during autoload
*
* This function self checks the EFUSE module.
*/
/* SourceId : SELFTEST_SourceId_011 */
/* DesignId : SELFTEST_DesignId_012 */
/* Requirements : HL_SR402 */
uint32_t tms570_efc_check( void )
{
uint32_t efc_status = 0U;
uint32_t status;
/* read the EFC Error Status Register */
efc_status = TMS570_EFUSE.EFC_ERR_STAT;
if ( efc_status == 0x0U ) {
/* run stuck-at-zero test and check if it passed */
if ( tms570_efc_stuck_zero() == true ) {
/* start EFC ECC logic self-test */
tms570_efc_self_test();
status = 0U;
} else {
/* EFC output is stuck-at-zero, device operation unreliable */
bsp_selftest_fail_notification( EFCCHECK_FAIL1 );
status = 1U;
}
}
/* EFC Error Register is not zero */
else {
/* one-bit error detected during autoload */
if ( efc_status == 0x15U ) {
/* start EFC ECC logic self-test */
tms570_efc_self_test();
status = 2U;
} else {
/* Some other EFC error was detected */
bsp_selftest_fail_notification( EFCCHECK_FAIL1 );
status = 3U;
}
}
return status;
}
/**
* @brief PBIST self test Driver (HCG:pbistSelfCheck)
*
* This function is called to perform PBIST self test.
*/
/* SourceId : SELFTEST_SourceId_005 */
/* DesignId : SELFTEST_DesignId_005 */
/* Requirements : HL_SR399 */
void tms570_pbist_self_check( void )
{
volatile uint32_t i = 0U;
uint32_t PBIST_wait_done_loop = 0U;
/* Run a diagnostic check on the memory self-test controller */
/* First set up the PBIST ROM clock as this clock frequency is limited to 90MHz */
/* Disable PBIST clocks and ROM clock */
TMS570_PBIST.PACT = 0x0U;
/* PBIST ROM clock frequency = HCLK frequency /2 */
/* Disable memory self controller */
TMS570_SYS1.MSTGCR = 0x00000105U;
/* Disable Memory Initialization controller */
TMS570_SYS1.MINITGCR = 0x5U;
/* Enable memory self controller */
TMS570_SYS1.MSTGCR = 0x0000010AU;
/* Clear PBIST Done */
TMS570_SYS1.MSTCGSTAT = 0x1U;
/* Enable PBIST controller */
TMS570_SYS1.MSIENA = 0x1U;
/* wait for 32 VBUS clock cycles at least, based on HCLK to VCLK ratio */
/*SAFETYMCUSW 134 S MR:12.2 <APPROVED> "Wait for few clock cycles (Value of i not used)" */
/*SAFETYMCUSW 134 S MR:12.2 <APPROVED> "Wait for few clock cycles (Value of i not used)" */
for ( i = 0U; i < ( 32U + ( 32U * 1U ) ); i++ ) { /* Wait */
}
/* Enable PBIST clocks and ROM clock */
TMS570_PBIST.PACT = 0x3U;
/* CPU control of PBIST */
TMS570_PBIST.DLR = 0x10U;
/* Custom always fail algo, this will not use the ROM and just set a fail */
TMS570_PBIST.RAMT = 0x00002000U;
*(volatile uint32_t *) 0xFFFFE400U = 0x4C000001U;
*(volatile uint32_t *) 0xFFFFE440U = 0x00000075U;
*(volatile uint32_t *) 0xFFFFE404U = 0x4C000002U;
*(volatile uint32_t *) 0xFFFFE444U = 0x00000075U;
*(volatile uint32_t *) 0xFFFFE408U = 0x4C000003U;
*(volatile uint32_t *) 0xFFFFE448U = 0x00000075U;
*(volatile uint32_t *) 0xFFFFE40CU = 0x4C000004U;
*(volatile uint32_t *) 0xFFFFE44CU = 0x00000075U;
*(volatile uint32_t *) 0xFFFFE410U = 0x4C000005U;
*(volatile uint32_t *) 0xFFFFE450U = 0x00000075U;
*(volatile uint32_t *) 0xFFFFE414U = 0x4C000006U;
*(volatile uint32_t *) 0xFFFFE454U = 0x00000075U;
*(volatile uint32_t *) 0xFFFFE418U = 0x00000000U;
*(volatile uint32_t *) 0xFFFFE458U = 0x00000001U;
/* PBIST_RUN */
( &TMS570_PBIST.DLR )[ 2 ] = 1;
/* wait until memory self-test done is indicated */
/*SAFETYMCUSW 28 D MR:NA <APPROVED> "Hardware status bit read check" */
while ( ( TMS570_SYS1.MSTCGSTAT & 0x1U ) != 0x1U )
PBIST_wait_done_loop++;
/* Wait */
/* Check for the failure */
if ( ( TMS570_PBIST.FSRF0 & 0x1U ) != 0x1U ) {
/* No failure was indicated even if the always fail algorithm was run*/
bsp_selftest_fail_notification( PBISTSELFCHECK_FAIL1 );
} else {
/* Check that the algorithm executed in the expected amount of time. */
/* This time is dependent on the ROMCLKDIV selected above */
if ( PBIST_wait_done_loop >= 2U ) {
bsp_selftest_fail_notification( PBISTSELFCHECK_FAIL2 );
}
/* Disable PBIST clocks and ROM clock */
TMS570_PBIST.PACT = 0x0U;
/* Disable PBIST */
TMS570_SYS1.MSTGCR &= 0xFFFFFFF0U;
TMS570_SYS1.MSTGCR |= 0x5U;
}
}
/**
* @brief CPU self test Driver (HCG:pbistRun)
* @param[in] raminfoL - Select the list of RAM to be tested.
* @param[in] algomask - Select the list of Algorithm to be run.
*
* This function performs Memory Built-in Self test using PBIST module.
*/
/* SourceId : SELFTEST_SourceId_006 */
/* DesignId : SELFTEST_DesignId_006 */
/* Requirements : HL_SR400 */
void tms570_pbist_run(
uint32_t raminfoL,
uint32_t algomask
)
{
volatile uint32_t i = 0U;
/* PBIST ROM clock frequency = HCLK frequency /2 */
/* Disable memory self controller */
TMS570_SYS1.MSTGCR = 0x00000105U;
/* Disable Memory Initialization controller */
TMS570_SYS1.MINITGCR = 0x5U;
/* Enable PBIST controller */
TMS570_SYS1.MSIENA = 0x1U;
/* Enable memory self controller */
TMS570_SYS1.MSTGCR = 0x0000010AU;
/* wait for 32 VBUS clock cycles at least, based on HCLK to VCLK ratio */
/*SAFETYMCUSW 134 S MR:12.2 <APPROVED> "Wait for few clock cycles (Value of i not used)" */
/*SAFETYMCUSW 134 S MR:12.2 <APPROVED> "Wait for few clock cycles (Value of i not used)" */
for ( i = 0U; i < ( 32U + ( 32U * 1U ) ); i++ ) { /* Wait */
}
/* Enable PBIST clocks and ROM clock */
TMS570_PBIST.PACT = 0x3U;
/* Select all algorithms to be tested */
TMS570_PBIST.ALGO = algomask;
/* Select RAM groups */
TMS570_PBIST.RINFOL = raminfoL;
/* Select all RAM groups */
TMS570_PBIST.RINFOUL = 0x00000000U;
/* ROM contents will not override RINFOx settings */
TMS570_PBIST.OVER = 0x0U;
/* Algorithm code is loaded from ROM */
TMS570_PBIST.ROM = 0x3U;
/* Start PBIST */
TMS570_PBIST.DLR = 0x14U;
}
/**
* @brief Routine to stop PBIST test enabled (HCG:pbistStop)
*
* This function is called to stop PBIST after test is performed.
*/
/* SourceId : SELFTEST_SourceId_007 */
/* DesignId : SELFTEST_DesignId_007 */
/* Requirements : HL_SR523 */
void tms570_pbist_stop( void )
{
/* disable pbist clocks and ROM clock */
TMS570_PBIST.PACT = 0x0U;
TMS570_SYS1.MSTGCR &= 0xFFFFFFF0U;
TMS570_SYS1.MSTGCR |= 0x5U;
}
/**
* @brief Checks to see if the PBIST test is completed (HCG:pbistIsTestCompleted)
* @return 1 if PBIST test completed, otherwise 0.
*
* Checks to see if the PBIST test is completed.
*/
/* SourceId : SELFTEST_SourceId_008 */
/* DesignId : SELFTEST_DesignId_008 */
/* Requirements : HL_SR401 */
bool tms570_pbist_is_test_completed( void )
{
return ( ( TMS570_SYS1.MSTCGSTAT & 0x1U ) != 0U );
}
/**
* @brief Checks to see if the PBIST test is completed successfully (HCG:pbistIsTestPassed)
* @return 1 if PBIST test passed, otherwise 0.
*
* Checks to see if the PBIST test is completed successfully.
*/
/* SourceId : SELFTEST_SourceId_009 */
/* DesignId : SELFTEST_DesignId_009 */
/* Requirements : HL_SR401 */
bool tms570_pbist_is_test_passed( void )
{
bool status;
if ( TMS570_PBIST.FSRF0 == 0U ) {
status = true;
} else {
status = false;
}
return status;
}
/**
* @brief Checks to see if the PBIST Port test is completed successfully (HCG:pbistPortTestStatus)
* @param[in] port - Select the port to get the status.
* @return 1 if PBIST Port test completed successfully, otherwise 0.
*
* Checks to see if the selected PBIST Port test is completed successfully.
*/
/* SourceId : SELFTEST_SourceId_010 */
/* DesignId : SELFTEST_DesignId_010 */
/* Requirements : HL_SR401 */
bool tms570_pbist_port_test_status( uint32_t port )
{
bool status;
if ( port == (uint32_t) PBIST_PORT0 ) {
status = ( TMS570_PBIST.FSRF0 == 0U );
} else {
/* Invalid Input */
status = false;
}
return status;
}
/**
* @brief Reaction to PBIST failure (HCG:pbistFail)
*
* @return Void.
*/
/* SourceId : SELFTEST_SourceId_042 */
/* DesignId : SELFTEST_DesignId_011 */
/* Requirements : HL_SR401 */
void tms570_pbist_fail( void )
{
uint32_t PBIST_RAMT, PBIST_FSRA0, PBIST_FSRDL0;
/*SAFETYMCUSW 134 S MR:12.2 <APPROVED> "LDRA Tool issue" */
PBIST_RAMT = TMS570_PBIST.RAMT;
PBIST_FSRA0 = TMS570_PBIST.FSRA0;
PBIST_FSRDL0 = TMS570_PBIST.FSRDL0;
if ( tms570_pbist_port_test_status( (uint32_t) PBIST_PORT0 ) != true ) {
uint32_t groupSelect = ( PBIST_RAMT & 0xFF000000U ) >> 24U;
uint32_t dataSelect = ( PBIST_RAMT & 0x00FF0000U ) >> 16U;
uint32_t address = PBIST_FSRA0;
uint32_t data = PBIST_FSRDL0;
tms570_memory_port0_fail_notification( groupSelect,
dataSelect,
address,
data );
} else {
/*SAFETYMCUSW 5 C MR:NA <APPROVED> "for(;;) can be removed by adding "# if 0" and "# endif" in the user codes above and below" */
/*SAFETYMCUSW 26 S MR:NA <APPROVED> "for(;;) can be removed by adding "# if 0" and "# endif" in the user codes above and below" */
/*SAFETYMCUSW 28 D MR:NA <APPROVED> "for(;;) can be removed by adding "# if 0" and "# endif" in the user codes above and below" */
for (;; ) {
} /* Wait */
}
}
/**
* @brief Memory Initialization Driver (HCG:memoryInit)
*
* This function is called to perform Memory initialization of selected RAM's.
*/
/* SourceId : SELFTEST_SourceId_002 */
/* DesignId : SELFTEST_DesignId_004 */
/* Requirements : HL_SR396 */
void tms570_memory_init( uint32_t ram )
{
/* Enable Memory Hardware Initialization */
TMS570_SYS1.MINITGCR = 0xAU;
/* Enable Memory Hardware Initialization for selected RAM's */
TMS570_SYS1.MSIENA = ram;
/* Wait until Memory Hardware Initialization complete */
/*SAFETYMCUSW 28 D MR:NA <APPROVED> "Hardware status bit read check" */
while ( ( TMS570_SYS1.MSTCGSTAT & 0x00000100U ) != 0x00000100U ) {
} /* Wait */
/* Disable Memory Hardware Initialization */
TMS570_SYS1.MINITGCR = 0x5U;
}
volatile uint32_t *const
tms570_esm_group_channel_to_sr_table[ 4 ][ 2 ] = {
{ NULL, NULL },
{ &TMS570_ESM.SR[ 0 ], &TMS570_ESM.SR4 },
{ &TMS570_ESM.SR[ 1 ], NULL },
{ &TMS570_ESM.SR[ 2 ], NULL },
};
/**
* @brief Routine to clear specified error channel signalling bit
* @param[in] grp - ESM error channels group
* @param[in] chan - ESM error channel number inside specified group
*/
void tms570_esm_channel_sr_clear(
unsigned grp,
unsigned chan
)
{
volatile uint32_t *sr_reg;
sr_reg = tms570_esm_group_channel_to_sr_table[ grp ][ chan >> 5 ];
if ( sr_reg != NULL )
*sr_reg = 1 << (chan & 0x1f);
}
/** tms570_esm_channel_sr_get
* @brief Routine to test is specified error channel is signalling error
* @param[in] grp - ESM error channels group
* @param[in] chan - ESM error channel number inside specified group
*/
int tms570_esm_channel_sr_get(
unsigned grp,
unsigned chan
)
{
volatile uint32_t *sr_reg;
sr_reg = tms570_esm_group_channel_to_sr_table[ grp ][ chan >> 5 ];
if ( sr_reg != NULL )
return *sr_reg & ( 1 << ( chan & 0x1f ) );
else
return 0;
}
/**
* @brief Enable peripheral RAM parity (HCG:enableParity)
*
* This function enables RAM parity for all peripherals for which RAM parity check is enabled.
* This function is called before memoryInit in the startup
*
*/
void tms570_enable_parity( void )
{
TMS570_DMA.DMAPCR = 0xAU; /* Enable DMA RAM parity */
TMS570_VIM.PARCTL = 0xAU; /* Enable VIM RAM parity */
TMS570_DCAN1.CTL = ((uint32_t)0xAU << 10U) | 1U; /* Enable CAN1 RAM parity */
TMS570_DCAN2.CTL = ((uint32_t)0xAU << 10U) | 1U; /* Enable CAN2 RAM parity */
TMS570_DCAN3.CTL = ((uint32_t)0xAU << 10U) | 1U; /* Enable CAN3 RAM parity */
TMS570_ADC1.PARCR = 0xAU; /* Enable ADC1 RAM parity */
TMS570_ADC2.PARCR = 0xAU; /* Enable ADC2 RAM parity */
TMS570_NHET1.PCR = 0xAU; /* Enable HET1 RAM parity */
TMS570_HTU1.PCR = 0xAU; /* Enable HTU1 RAM parity */
TMS570_NHET2.PCR = 0xAU; /* Enable HET2 RAM parity */
TMS570_HTU2.PCR = 0xAU; /* Enable HTU2 RAM parity */
}
/**
* @brief Disable peripheral RAM parity (HCG:disableParity)
*
* This function disables RAM parity for all peripherals for which RAM parity check is enabled.
* This function is called after memoryInit in the startup
*
*/
void tms570_disable_parity( void )
{
TMS570_DMA.DMAPCR = 0x5U; /* Disable DMA RAM parity */
TMS570_VIM.PARCTL = 0x5U; /* Disable VIM RAM parity */
TMS570_DCAN1.CTL = ((uint32_t)0x5U << 10U) | 1U; /* Disable CAN1 RAM parity */
TMS570_DCAN2.CTL = ((uint32_t)0x5U << 10U) | 1U; /* Disable CAN2 RAM parity */
TMS570_DCAN3.CTL = ((uint32_t)0x5U << 10U) | 1U; /* Disable CAN3 RAM parity */
TMS570_ADC1.PARCR = 0x5U; /* Disable ADC1 RAM parity */
TMS570_ADC2.PARCR = 0x5U; /* Disable ADC2 RAM parity */
TMS570_NHET1.PCR = 0x5U; /* Disable HET1 RAM parity */
TMS570_HTU1.PCR = 0x5U; /* Disable HTU1 RAM parity */
TMS570_NHET2.PCR = 0x5U; /* Disable HET2 RAM parity */
TMS570_HTU2.PCR = 0x5U; /* Disable HTU2 RAM parity */
}

View File

@@ -0,0 +1,214 @@
/**
* @file tms570_selftest.h
*
* @ingroup tms570
*
* @brief Definition of TMS570 selftest error codes, addresses and functions.
*/
/*
* Copyright (c) 2016 Pavel Pisa <pisa@cmp.felk.cvut.cz>
*
* Czech Technical University in Prague
* Zikova 1903/4
* 166 36 Praha 6
* Czech Republic
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
*
* Algorithms are based on Ti manuals and Ti HalCoGen generated
* code available under following copyright.
*/
/*
* Copyright (C) 2009-2015 Texas Instruments Incorporated - 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 LIBBSP_ARM_TMS570_SELFTEST_H
#define LIBBSP_ARM_TMS570_SELFTEST_H
#include <stdint.h>
#include <stdbool.h>
#define CCMSELFCHECK_FAIL1 1U
#define CCMSELFCHECK_FAIL2 2U
#define CCMSELFCHECK_FAIL3 3U
#define CCMSELFCHECK_FAIL4 4U
#define PBISTSELFCHECK_FAIL1 5U
#define EFCCHECK_FAIL1 6U
#define EFCCHECK_FAIL2 7U
#define FMCECCCHECK_FAIL1 8U
#define CHECKB0RAMECC_FAIL1 9U
#define CHECKB1RAMECC_FAIL1 10U
#define CHECKFLASHECC_FAIL1 11U
#define VIMPARITYCHECK_FAIL1 12U
#define DMAPARITYCHECK_FAIL1 13U
#define HET1PARITYCHECK_FAIL1 14U
#define HTU1PARITYCHECK_FAIL1 15U
#define HET2PARITYCHECK_FAIL1 16U
#define HTU2PARITYCHECK_FAIL1 17U
#define ADC1PARITYCHECK_FAIL1 18U
#define ADC2PARITYCHECK_FAIL1 19U
#define CAN1PARITYCHECK_FAIL1 20U
#define CAN2PARITYCHECK_FAIL1 21U
#define CAN3PARITYCHECK_FAIL1 22U
#define MIBSPI1PARITYCHECK_FAIL1 23U
#define MIBSPI3PARITYCHECK_FAIL1 24U
#define MIBSPI5PARITYCHECK_FAIL1 25U
#define CHECKRAMECC_FAIL1 26U
#define CHECKRAMECC_FAIL2 27U
#define CHECKCLOCKMONITOR_FAIL1 28U
#define CHECKFLASHEEPROMECC_FAIL1 29U
#define CHECKFLASHEEPROMECC_FAIL2 31U
#define CHECKFLASHEEPROMECC_FAIL3 32U
#define CHECKFLASHEEPROMECC_FAIL4 33U
#define CHECKPLL1SLIP_FAIL1 34U
#define CHECKRAMADDRPARITY_FAIL1 35U
#define CHECKRAMADDRPARITY_FAIL2 36U
#define CHECKRAMUERRTEST_FAIL1 37U
#define CHECKRAMUERRTEST_FAIL2 38U
#define FMCBUS1PARITYCHECK_FAIL1 39U
#define FMCBUS1PARITYCHECK_FAIL2 40U
#define PBISTSELFCHECK_FAIL2 41U
#define PBISTSELFCHECK_FAIL3 42U
/* PBIST and STC ROM - PBIST RAM GROUPING */
#define PBIST_ROM_PBIST_RAM_GROUP 1U
#define STC_ROM_PBIST_RAM_GROUP 2U
#define VIMRAMLOC (*(volatile uint32_t *)0xFFF82000U)
#define VIMRAMPARLOC (*(volatile uint32_t *)0xFFF82400U)
#define NHET1RAMPARLOC (*(volatile uint32_t *)0xFF462000U)
#define NHET2RAMPARLOC (*(volatile uint32_t *)0xFF442000U)
#define adcPARRAM1 (*(volatile uint32_t *)(0xFF3E0000U + 0x1000U))
#define adcPARRAM2 (*(volatile uint32_t *)(0xFF3A0000U + 0x1000U))
#define canPARRAM1 (*(volatile uint32_t *)(0xFF1E0000U + 0x10U))
#define canPARRAM2 (*(volatile uint32_t *)(0xFF1C0000U + 0x10U))
#define canPARRAM3 (*(volatile uint32_t *)(0xFF1A0000U + 0x10U))
#define HTU1PARLOC (*(volatile uint32_t *)0xFF4E0200U)
#define HTU2PARLOC (*(volatile uint32_t *)0xFF4C0200U)
#define NHET1RAMLOC (*(volatile uint32_t *)0xFF460000U)
#define NHET2RAMLOC (*(volatile uint32_t *)0xFF440000U)
#define HTU1RAMLOC (*(volatile uint32_t *)0xFF4E0000U)
#define HTU2RAMLOC (*(volatile uint32_t *)0xFF4C0000U)
#define adcRAM1 (*(volatile uint32_t *)0xFF3E0000U)
#define adcRAM2 (*(volatile uint32_t *)0xFF3A0000U)
#define canRAM1 (*(volatile uint32_t *)0xFF1E0000U)
#define canRAM2 (*(volatile uint32_t *)0xFF1C0000U)
#define canRAM3 (*(volatile uint32_t *)0xFF1A0000U)
#define DMARAMPARLOC (*(volatile uint32_t *)(0xFFF80A00U))
#define DMARAMLOC (*(volatile uint32_t *)(0xFFF80000U))
#define MIBSPI1RAMLOC (*(volatile uint32_t *)(0xFF0E0000U))
#define MIBSPI3RAMLOC (*(volatile uint32_t *)(0xFF0C0000U))
#define MIBSPI5RAMLOC (*(volatile uint32_t *)(0xFF0A0000U))
#define mibspiPARRAM1 (*(volatile uint32_t *)(0xFF0E0000U + 0x00000400U))
#define mibspiPARRAM3 (*(volatile uint32_t *)(0xFF0C0000U + 0x00000400U))
#define mibspiPARRAM5 (*(volatile uint32_t *)(0xFF0A0000U + 0x00000400U))
/** @enum pbistPort
* @brief Alias names for pbist Port number
*
* This enumeration is used to provide alias names for the pbist Port number
* - PBIST_PORT0
* - PBIST_PORT1
*
* @Note Check the datasheet for the port avaiability
*/
enum pbistPort {
PBIST_PORT0 = 0U, /**< Alias for PBIST Port 0 */
PBIST_PORT1 = 1U /**< Alias for PBIST Port 1 < Check datasheet for Port 1 availability > */
};
enum {
PBIST_TripleReadSlow = 0x00000001U, /**<TRIPLE_READ_SLOW_READ for PBIST and STC ROM*/
PBIST_TripleReadFast = 0x00000002U, /**<TRIPLE_READ_SLOW_READ for PBIST and STC ROM*/
PBIST_March13N_DP = 0x00000004U, /**< March13 N Algo for 2 Port mem */
};
uint32_t tms570_efc_check( void );
bool tms570_efc_check_self_test( void );
void bsp_selftest_fail_notification( uint32_t flag );
void tms570_memory_port0_fail_notification(
uint32_t groupSelect,
uint32_t dataSelect,
uint32_t address,
uint32_t data
);
void tms570_esm_channel_sr_clear(
unsigned grp,
unsigned chan
);
int tms570_esm_channel_sr_get(
unsigned grp,
unsigned chan
);
void tms570_pbist_self_check( void );
void tms570_pbist_run(
uint32_t raminfoL,
uint32_t algomask
);
bool tms570_pbist_is_test_completed( void );
bool tms570_pbist_is_test_passed( void );
void tms570_pbist_fail( void );
void tms570_pbist_stop( void );
void tms570_enable_parity( void );
void tms570_disable_parity( void );
bool tms570_efc_stuck_zero( void );
void tms570_efc_self_test( void );
bool tms570_pbist_port_test_status( uint32_t port );
void tms570_check_tcram_ecc( void );
#endif /*LIBBSP_ARM_TMS570_SELFTEST_H*/

View File

@@ -0,0 +1,93 @@
/**
* @file tms570_selftest_par_can.c
*
* @ingroup tms570
*
* @brief Test CAN module parity based protection logic to work.
*/
/*
* Copyright (c) 2016 Pavel Pisa <pisa@cmp.felk.cvut.cz>
*
* Czech Technical University in Prague
* Zikova 1903/4
* 166 36 Praha 6
* Czech Republic
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
*
* Algorithms are based on Ti manuals and Ti HalCoGen generated
* code.
*/
#include <stdint.h>
#include <stddef.h>
#include <bsp/tms570.h>
#include "tms570_selftest.h"
#include "tms570_selftest_parity.h"
/**
* @brief run test to check that parity protection works for CAN modules RAM
*
* @param[in] desc module registers addresses end ESM channels descriptor
*
* @return Void, in the case of error invokes bsp_selftest_fail_notification()
*
* The descriptor provides address of the module registers and address
* of internal RAM memory and corresponding parity area test access window.
*/
void tms570_selftest_par_check_can( const tms570_selftest_par_desc_t *desc )
{
volatile uint32_t test_read_data;
volatile tms570_dcan_t *can_regs = (volatile tms570_dcan_t *) desc->fnc_data;
uint32_t canctl_bak = can_regs->CTL;
uint32_t canctl_pmd;
int perr;
/* Set TEST mode and enable parity checking */
/* Disable parity, init mode, TEST mode */
canctl_pmd = TMS570_DCAN_CTL_PMD_SET( 0, 0x5 );
can_regs->CTL = canctl_pmd | TMS570_DCAN_CTL_Test | TMS570_DCAN_CTL_Init;
/* Enable RAM Direct Access mode */
can_regs->TEST = TMS570_DCAN_TEST_RDA;
/* flip parity bit */
*desc->par_loc ^= desc->par_xor;
/* Disable TEST mode */
canctl_pmd = TMS570_DCAN_CTL_PMD_SET( 0, 0xA );
can_regs->CTL = canctl_pmd | TMS570_DCAN_CTL_Test;
/* read to cause parity error */
test_read_data = *desc->ram_loc;
(void) test_read_data;
/* check if ESM channel is flagged */
perr = tms570_esm_channel_sr_get( desc->esm_prim_grp, desc->esm_prim_chan );
if ( !perr ) {
/* RAM parity error was not flagged to ESM. */
bsp_selftest_fail_notification( desc->fail_code );
} else {
/* clear ESM flag */
tms570_esm_channel_sr_clear( desc->esm_prim_grp, desc->esm_prim_chan );
/* Set TEST mode and enable parity checking */
canctl_pmd = TMS570_DCAN_CTL_PMD_SET( 0, 0x5 );
can_regs->CTL = canctl_pmd | TMS570_DCAN_CTL_Test | TMS570_DCAN_CTL_Init;
/* Revert back to correct data by flipping parity location */
*desc->par_loc ^= desc->par_xor;
}
/* Disable RAM Direct Access mode */
can_regs->TEST = 0x00000000U;
/* Restore CTL register */
can_regs->CTL = canctl_bak;
/* Read Error and Status register to clear Parity Error bit */
test_read_data = can_regs->ES;
}

View File

@@ -0,0 +1,105 @@
/**
* @file tms570_selftest_par_can.c
*
* @ingroup tms570
*
* @brief Test MibSPI module parity based protection logic to work.
*/
/*
* Copyright (c) 2016 Pavel Pisa <pisa@cmp.felk.cvut.cz>
*
* Czech Technical University in Prague
* Zikova 1903/4
* 166 36 Praha 6
* Czech Republic
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
*
* Algorithms are based on Ti manuals and Ti HalCoGen generated
* code.
*/
#include <stdint.h>
#include <stddef.h>
#include <bsp/tms570.h>
#include "tms570_selftest.h"
#include "tms570_selftest_parity.h"
/**
* @brief run test to check that parity protection works for MibSPI modules RAM
*
* @param[in] desc module registers addresses end ESM channels descriptor
*
* @return Void, in the case of error invokes bsp_selftest_fail_notification()
*
* The descriptor provides address of the module registers and address
* of internal RAM memory and corresponding parity area test access window.
*/
void tms570_selftest_par_check_mibspi( const tms570_selftest_par_desc_t *desc )
{
volatile uint32_t test_read_data;
volatile tms570_spi_t *spi_regs = (volatile tms570_spi_t *) desc->fnc_data;
uint32_t mibspie_bak;
uint32_t uerrctl_bak;
int perr;
int wait_timeout = 10000;
/* wait for MibSPI RAM to complete initialization */
while ( ( spi_regs->FLG & TMS570_SPI_FLG_BUFINITACTIVE ) ==
TMS570_SPI_FLG_BUFINITACTIVE ) {
if ( !wait_timeout-- ) {
bsp_selftest_fail_notification( desc->fail_code );
}
}
/* Store previous configuration of MibSPI */
mibspie_bak = spi_regs->MIBSPIE;
uerrctl_bak = spi_regs->UERRCTRL;
/* enable multi-buffered mode */
spi_regs->MIBSPIE = TMS570_SPI_MIBSPIE_MSPIENA;
/* enable parity error detection */
spi_regs->UERRCTRL = TMS570_SPI_UERRCTRL_EDEN_SET( spi_regs->UERRCTRL,
TMS570_SELFTEST_PAR_CR_KEY );
/* enable parity test mode */
spi_regs->UERRCTRL |= TMS570_SPI_UERRCTRL_PTESTEN;
/* flip parity bit */
*desc->par_loc ^= desc->par_xor;
/* disable parity TEST mode */
spi_regs->UERRCTRL &= ~TMS570_SPI_UERRCTRL_PTESTEN;
/* read to cause parity error */
test_read_data = *desc->ram_loc;
(void) test_read_data;
/* check if ESM channel is flagged */
perr = tms570_esm_channel_sr_get( desc->esm_prim_grp, desc->esm_prim_chan );
if ( !perr ) {
/* RAM parity error was not flagged to ESM. */
bsp_selftest_fail_notification( desc->fail_code );
} else {
/* clear parity error flags */
spi_regs->UERRSTAT = TMS570_SPI_UERRSTAT_EDFLG1 |
TMS570_SPI_UERRSTAT_EDFLG0;
/* clear ESM flag */
tms570_esm_channel_sr_clear( desc->esm_prim_grp, desc->esm_prim_chan );
/* enable parity test mode */
spi_regs->UERRCTRL |= TMS570_SPI_UERRCTRL_PTESTEN;
/* Revert back to correct data by flipping parity location */
*desc->par_loc ^= desc->par_xor;
}
/* Restore MIBSPI control registers */
spi_regs->UERRCTRL = uerrctl_bak;
spi_regs->MIBSPIE = mibspie_bak;
}

View File

@@ -0,0 +1,90 @@
/**
* @file tms570_selftest_par_std.c
*
* @ingroup tms570
*
* @brief Generic parity based protection logic check applicable to HETx, HTUx, ADC, DMA and VIM.
*/
/*
* Copyright (c) 2016 Pavel Pisa <pisa@cmp.felk.cvut.cz>
*
* Czech Technical University in Prague
* Zikova 1903/4
* 166 36 Praha 6
* Czech Republic
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
*
* Algorithms are based on Ti manuals and Ti HalCoGen generated
* code.
*/
#include <stdint.h>
#include <stddef.h>
#include <bsp/tms570.h>
#include "tms570_selftest.h"
#include "tms570_selftest_parity.h"
/**
* @brief run test to check that parity protection works for modules with common setup structure.
*
* @param[in] desc module registers addresses end ESM channels descriptor
*
* @return Void, in the case of error invokes bsp_selftest_fail_notification()
*
* The descriptor provides address of the module registers and address
* of internal RAM memory and corresponding parity area test access window.
* This test function is usable for HETx, HTUx, ADC, DMA and VIM TMS570
* peripherals.
*/
void tms570_selftest_par_check_std( const tms570_selftest_par_desc_t *desc )
{
volatile uint32_t test_read_data;
uint32_t par_cr_bak = *desc->par_cr_reg;
int perr;
/* Set TEST mode and enable parity checking */
*desc->par_cr_reg = desc->par_cr_test | TMS570_SELFTEST_PAR_CR_KEY;
/* flip parity bit */
*desc->par_loc ^= desc->par_xor;
/* Disable TEST mode */
*desc->par_cr_reg = TMS570_SELFTEST_PAR_CR_KEY;
/* read to cause parity error */
test_read_data = *desc->ram_loc;
(void) test_read_data;
/* check if ESM channel is flagged */
perr = tms570_esm_channel_sr_get( desc->esm_prim_grp, desc->esm_prim_chan );
if ( desc->esm_sec_grp )
perr |= tms570_esm_channel_sr_get( desc->esm_sec_grp, desc->esm_sec_chan );
if ( !perr ) {
/* RAM parity error was not flagged to ESM. */
bsp_selftest_fail_notification( desc->fail_code );
} else {
/* If periperal has it own parity status register, clear it */
if ( desc->par_st_reg != NULL )
*desc->par_st_reg = desc->par_st_clear;
/* clear ESM flag */
tms570_esm_channel_sr_clear( desc->esm_prim_grp, desc->esm_prim_chan );
if ( desc->esm_sec_grp )
tms570_esm_channel_sr_clear( desc->esm_sec_grp, desc->esm_sec_chan );
/* Set TEST mode and enable parity checking */
*desc->par_cr_reg = desc->par_cr_test | TMS570_SELFTEST_PAR_CR_KEY;
/* Revert back to correct data by flipping parity location */
*desc->par_loc ^= desc->par_xor;
}
/* Restore Parity comtrol register */
*desc->par_cr_reg = par_cr_bak;
}

View File

@@ -0,0 +1,316 @@
/**
* @file tms570_selftest_parity.c
*
* @ingroup tms570
*
* @brief Check of module parity based protection logic to work.
*/
/*
* Copyright (c) 2016 Pavel Pisa <pisa@cmp.felk.cvut.cz>
*
* Czech Technical University in Prague
* Zikova 1903/4
* 166 36 Praha 6
* Czech Republic
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
*/
#include <stdint.h>
#include <stddef.h>
#include <bsp/tms570.h>
#include <rtems.h>
#include "tms570_selftest.h"
#include "tms570_selftest_parity.h"
/* HCG:het1ParityCheck */
const tms570_selftest_par_desc_t
tms570_selftest_par_het1_desc = {
.esm_prim_grp = 1,
.esm_prim_chan = 7,
.esm_sec_grp = 0,
.esm_sec_chan = 0,
.fail_code = HET1PARITYCHECK_FAIL1,
.ram_loc = &NHET1RAMLOC,
.par_loc = &NHET1RAMPARLOC,
.par_xor = 0x00000001,
.par_cr_reg = &TMS570_NHET1.PCR,
.par_cr_test = TMS570_NHET_PCR_TEST,
.par_st_reg = NULL,
.par_st_clear = 0,
.partest_fnc = tms570_selftest_par_check_std,
.fnc_data = NULL
};
/* HCG:htu1ParityCheck */
const tms570_selftest_par_desc_t
tms570_selftest_par_htu1_desc = {
.esm_prim_grp = 1,
.esm_prim_chan = 8,
.esm_sec_grp = 0,
.esm_sec_chan = 0,
.fail_code = HTU1PARITYCHECK_FAIL1,
.ram_loc = &HTU1RAMLOC,
.par_loc = &HTU1PARLOC,
.par_xor = 0x00000001,
.par_cr_reg = &TMS570_HTU1.PCR,
.par_cr_test = TMS570_HTU_PCR_TEST,
.par_st_reg = &TMS570_HTU1.PAR,
.par_st_clear = TMS570_HTU_PAR_PEFT,
.partest_fnc = tms570_selftest_par_check_std,
.fnc_data = NULL
};
/* HCG:het2ParityCheck */
const tms570_selftest_par_desc_t
tms570_selftest_par_het2_desc = {
.esm_prim_grp = 1,
.esm_prim_chan = 7,
.esm_sec_grp = 1,
.esm_sec_chan = 34,
.fail_code = HET2PARITYCHECK_FAIL1,
.ram_loc = &NHET2RAMLOC,
.par_loc = &NHET2RAMPARLOC,
.par_xor = 0x00000001,
.par_cr_reg = &TMS570_NHET2.PCR,
.par_cr_test = TMS570_NHET_PCR_TEST,
.par_st_reg = NULL,
.par_st_clear = 0,
.partest_fnc = tms570_selftest_par_check_std,
.fnc_data = NULL
};
/* HCG:htu2ParityCheck */
const tms570_selftest_par_desc_t
tms570_selftest_par_htu2_desc = {
.esm_prim_grp = 1,
.esm_prim_chan = 8,
.esm_sec_grp = 0,
.esm_sec_chan = 0,
.fail_code = HTU2PARITYCHECK_FAIL1,
.ram_loc = &HTU2RAMLOC,
.par_loc = &HTU2PARLOC,
.par_xor = 0x00000001,
.par_cr_reg = &TMS570_HTU2.PCR,
.par_cr_test = TMS570_HTU_PCR_TEST,
.par_st_reg = &TMS570_HTU2.PAR,
.par_st_clear = TMS570_HTU_PAR_PEFT,
.partest_fnc = tms570_selftest_par_check_std,
.fnc_data = NULL
};
/* HCG:adc1ParityCheck */
const tms570_selftest_par_desc_t
tms570_selftest_par_adc1_desc = {
.esm_prim_grp = 1,
.esm_prim_chan = 19,
.esm_sec_grp = 0,
.esm_sec_chan = 0,
.fail_code = ADC1PARITYCHECK_FAIL1,
.ram_loc = &adcRAM1,
.par_loc = &adcPARRAM1,
.par_xor = 0xffffffff,
.par_cr_reg = &TMS570_ADC1.PARCR,
.par_cr_test = TMS570_ADC_PARCR_TEST,
.par_st_reg = NULL,
.par_st_clear = 0,
.partest_fnc = tms570_selftest_par_check_std,
.fnc_data = NULL
};
/* HCG:adc2ParityCheck */
const tms570_selftest_par_desc_t
tms570_selftest_par_adc2_desc = {
.esm_prim_grp = 1,
.esm_prim_chan = 1,
.esm_sec_grp = 0,
.esm_sec_chan = 0,
.fail_code = ADC2PARITYCHECK_FAIL1,
.ram_loc = &adcRAM2,
.par_loc = &adcPARRAM2,
.par_xor = 0xffffffff,
.par_cr_reg = &TMS570_ADC2.PARCR,
.par_cr_test = TMS570_ADC_PARCR_TEST,
.par_st_reg = NULL,
.par_st_clear = 0,
.partest_fnc = tms570_selftest_par_check_std,
.fnc_data = NULL
};
/* HCG:can1ParityCheck */
const tms570_selftest_par_desc_t
tms570_selftest_par_can1_desc = {
.esm_prim_grp = 1,
.esm_prim_chan = 21,
.esm_sec_grp = 0,
.esm_sec_chan = 0,
.fail_code = CAN1PARITYCHECK_FAIL1,
.ram_loc = &canRAM1,
.par_loc = &canPARRAM1,
.par_xor = 0x00001000,
.par_cr_reg = NULL,
.par_cr_test = 0,
.par_st_reg = NULL,
.par_st_clear = 0,
.partest_fnc = tms570_selftest_par_check_can,
.fnc_data = &TMS570_DCAN1
};
/* HCG:can2ParityCheck */
const tms570_selftest_par_desc_t
tms570_selftest_par_can2_desc = {
.esm_prim_grp = 1,
.esm_prim_chan = 23,
.esm_sec_grp = 0,
.esm_sec_chan = 0,
.fail_code = CAN2PARITYCHECK_FAIL1,
.ram_loc = &canRAM2,
.par_loc = &canPARRAM2,
.par_xor = 0x00001000,
.par_cr_reg = NULL,
.par_cr_test = 0,
.par_st_reg = NULL,
.par_st_clear = 0,
.partest_fnc = tms570_selftest_par_check_can,
.fnc_data = &TMS570_DCAN2
};
/* HCG:can3ParityCheck */
const tms570_selftest_par_desc_t
tms570_selftest_par_can3_desc = {
.esm_prim_grp = 1,
.esm_prim_chan = 22,
.esm_sec_grp = 0,
.esm_sec_chan = 0,
.fail_code = CAN3PARITYCHECK_FAIL1,
.ram_loc = &canRAM3,
.par_loc = &canPARRAM3,
.par_xor = 0x00001000,
.par_cr_reg = NULL,
.par_cr_test = 0,
.par_st_reg = NULL,
.par_st_clear = 0,
.partest_fnc = tms570_selftest_par_check_can,
.fnc_data = &TMS570_DCAN3
};
/* HCG:vimParityCheck */
const tms570_selftest_par_desc_t
tms570_selftest_par_vim_desc = {
.esm_prim_grp = 1,
.esm_prim_chan = 15,
.esm_sec_grp = 0,
.esm_sec_chan = 0,
.fail_code = VIMPARITYCHECK_FAIL1,
.ram_loc = &VIMRAMLOC,
.par_loc = &VIMRAMPARLOC,
.par_xor = 0x00000001,
.par_cr_reg = &TMS570_VIM.PARCTL,
.par_cr_test = TMS570_VIM_PARCTL_TEST,
.par_st_reg = &TMS570_VIM.PARFLG,
.par_st_clear = TMS570_VIM_PARFLG_PARFLG,
.partest_fnc = tms570_selftest_par_check_std,
.fnc_data = NULL
};
/* HCG:dmaParityCheck */
const tms570_selftest_par_desc_t
tms570_selftest_par_dma_desc = {
.esm_prim_grp = 1,
.esm_prim_chan = 3,
.esm_sec_grp = 0,
.esm_sec_chan = 0,
.fail_code = DMAPARITYCHECK_FAIL1,
.ram_loc = &DMARAMLOC,
.par_loc = &DMARAMPARLOC,
.par_xor = 0x00000001,
.par_cr_reg = &TMS570_DMA.DMAPCR,
.par_cr_test = TMS570_DMA_DMAPCR_TEST,
.par_st_reg = &TMS570_DMA.DMAPAR,
.par_st_clear = TMS570_DMA_DMAPAR_EDFLAG,
.partest_fnc = tms570_selftest_par_check_std,
.fnc_data = NULL
};
/* HCG:mibspi1ParityCheck */
const tms570_selftest_par_desc_t
tms570_selftest_par_spi1_desc = {
.esm_prim_grp = 1,
.esm_prim_chan = 17,
.esm_sec_grp = 0,
.esm_sec_chan = 0,
.fail_code = MIBSPI1PARITYCHECK_FAIL1,
.ram_loc = &MIBSPI1RAMLOC,
.par_loc = &mibspiPARRAM1,
.par_xor = 0x00000001,
.par_cr_reg = NULL,
.par_cr_test = 0,
.par_st_reg = NULL,
.par_st_clear = 0,
.partest_fnc = tms570_selftest_par_check_mibspi,
.fnc_data = &TMS570_SPI1
};
/* HCG:mibspi3ParityCheck */
const tms570_selftest_par_desc_t
tms570_selftest_par_spi3_desc = {
.esm_prim_grp = 1,
.esm_prim_chan = 18,
.esm_sec_grp = 0,
.esm_sec_chan = 0,
.fail_code = MIBSPI3PARITYCHECK_FAIL1,
.ram_loc = &MIBSPI3RAMLOC,
.par_loc = &mibspiPARRAM3,
.par_xor = 0x00000001,
.par_cr_reg = NULL,
.par_cr_test = 0,
.par_st_reg = NULL,
.par_st_clear = 0,
.partest_fnc = tms570_selftest_par_check_mibspi,
.fnc_data = &TMS570_SPI3
};
/* HCG:mibspi5ParityCheck */
const tms570_selftest_par_desc_t
tms570_selftest_par_spi5_desc = {
.esm_prim_grp = 1,
.esm_prim_chan = 24,
.esm_sec_grp = 0,
.esm_sec_chan = 0,
.fail_code = MIBSPI5PARITYCHECK_FAIL1,
.ram_loc = &MIBSPI5RAMLOC,
.par_loc = &mibspiPARRAM5,
.par_xor = 0x00000001,
.par_cr_reg = NULL,
.par_cr_test = 0,
.par_st_reg = NULL,
.par_st_clear = 0,
.partest_fnc = tms570_selftest_par_check_mibspi,
.fnc_data = &TMS570_SPI5
};
/**
* @brief run parity protection mechanism check for set of modules described by list.
*
* @param[in] desc_arr array of pointers to descriptors providing addresses
* and ESM channels for individual peripherals.
* @param[in] desc_cnt count of pointers in the array
*
* @return Void, in the case of error invokes bsp_selftest_fail_notification()
*/
void tms570_selftest_par_run(
const tms570_selftest_par_desc_t *
const *desc_arr,
int desc_cnt
)
{
int i;
const tms570_selftest_par_desc_t *desc;
for ( i = 0; i < desc_cnt; i++ ) {
desc = desc_arr[ i ];
desc->partest_fnc( desc );
}
}

View File

@@ -0,0 +1,110 @@
/**
* @file tms570_selftest_parity.h
*
* @ingroup tms570
*
* @brief Check of module parity based protection logic to work.
*/
/*
* Copyright (c) 2016 Pavel Pisa <pisa@cmp.felk.cvut.cz>
*
* Czech Technical University in Prague
* Zikova 1903/4
* 166 36 Praha 6
* Czech Republic
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
*/
#ifndef LIBBSP_ARM_TMS570_SELFTEST_PARITY_H
#define LIBBSP_ARM_TMS570_SELFTEST_PARITY_H
#include <stdint.h>
/**
* The magic number used to switch most of the peripherals
* into parity protection test mode
*/
#define TMS570_SELFTEST_PAR_CR_KEY 0xA
typedef struct tms570_selftest_par_desc tms570_selftest_par_desc_t;
typedef void tms570_selftest_par_fnc_t( const tms570_selftest_par_desc_t *desc );
/**
* Decriptor specifying registers addresses and values used to test
* that parity protection is working for given hardware
* module/peripheral. It is used during initial chip self-tests.
*/
struct tms570_selftest_par_desc {
unsigned char esm_prim_grp; /**< ESM primary signalling group number. */
unsigned char esm_prim_chan; /**< ESM primary signalling channel number. */
unsigned char esm_sec_grp; /**< ESM optional/alternative signalling group. */
unsigned char esm_sec_chan; /**< ESM optional/alternative signalling channel. */
int fail_code; /**< Error code reported to
bsp_selftest_fail_notification() in the case of the test failure. */
volatile uint32_t *ram_loc; /**< Address of memory protected by parity. */
volatile uint32_t *par_loc; /**< Address of mapping of parity bits into CPU
* address space. */
uint32_t par_xor; /**< Bitmask used to alter parity to cause
* intentional parity failure. */
volatile uint32_t *par_cr_reg; /**< Address of module parity test control register. */
uint32_t par_cr_test; /**< Mask of bit which cause switch to a test mode. */
volatile uint32_t *par_st_reg; /**< Optional module parity status register which. */
uint32_t par_st_clear; /**< Optional value which is written to status register
* to clear error. */
tms570_selftest_par_fnc_t *partest_fnc; /**< Function which specialized for given kind
* of peripheral/module mechanism testing. */
volatile void *fnc_data; /**< Pointer to the base of tested peripheral registers.
* It is required by some test functions (CAN and MibSPI) */
};
extern const tms570_selftest_par_desc_t
tms570_selftest_par_het1_desc;
extern const tms570_selftest_par_desc_t
tms570_selftest_par_htu1_desc;
extern const tms570_selftest_par_desc_t
tms570_selftest_par_het2_desc;
extern const tms570_selftest_par_desc_t
tms570_selftest_par_htu2_desc;
extern const tms570_selftest_par_desc_t
tms570_selftest_par_adc1_desc;
extern const tms570_selftest_par_desc_t
tms570_selftest_par_adc2_desc;
extern const tms570_selftest_par_desc_t
tms570_selftest_par_can1_desc;
extern const tms570_selftest_par_desc_t
tms570_selftest_par_can2_desc;
extern const tms570_selftest_par_desc_t
tms570_selftest_par_can3_desc;
extern const tms570_selftest_par_desc_t
tms570_selftest_par_vim_desc;
const tms570_selftest_par_desc_t
tms570_selftest_par_dma_desc;
const tms570_selftest_par_desc_t
tms570_selftest_par_spi1_desc;
const tms570_selftest_par_desc_t
tms570_selftest_par_spi3_desc;
const tms570_selftest_par_desc_t
tms570_selftest_par_spi5_desc;
extern const tms570_selftest_par_desc_t *const
tms570_selftest_par_list[];
extern const int tms570_selftest_par_list_size;
void tms570_selftest_par_check_std( const tms570_selftest_par_desc_t *desc );
void tms570_selftest_par_check_can( const tms570_selftest_par_desc_t *desc );
void tms570_selftest_par_check_mibspi( const tms570_selftest_par_desc_t *desc );
void tms570_selftest_par_run(
const tms570_selftest_par_desc_t *
const *desc_arr,
int desc_cnt
);
#endif /* LIBBSP_ARM_TMS570_SELFTEST_PARITY_H */

View File

@@ -0,0 +1,575 @@
/*--------------------------------------------------------------------------
tms570_sys_core.S
Copyright (C) 2009-2015 Texas Instruments Incorporated - 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.
-------------------------------------------------------------------------*/
.section .text
.syntax unified
.cpu cortex-r4
.arm
/*-------------------------------------------------------------------------------*/
@ Initialize CPU Registers
@ SourceId : CORE_SourceId_001
@ DesignId : CORE_DesignId_001
@ Requirements: HL_SR477, HL_SR476, HL_SR492
.weak _coreInitRegisters_
.type _coreInitRegisters_, %function
_coreInitRegisters_:
@ After reset, the CPU is in the Supervisor mode (M = 10011)
mov r0, lr
mov r1, #0x0000
mov r2, #0x0000
mov r3, #0x0000
mov r4, #0x0000
mov r5, #0x0000
mov r6, #0x0000
mov r7, #0x0000
mov r8, #0x0000
mov r9, #0x0000
mov r10, #0x0000
mov r11, #0x0000
mov r12, #0x0000
mov r13, #0x0000
mrs r1, cpsr
msr spsr_cxsf, r1
@ Switch to FIQ mode (M = 10001)
cps #17
mov lr, r0
mov r8, #0x0000
mov r9, #0x0000
mov r10, #0x0000
mov r11, #0x0000
mov r12, #0x0000
mrs r1, cpsr
msr spsr_cxsf, r1
@ Switch to IRQ mode (M = 10010)
cps #18
mov lr, r0
mrs r1,cpsr
msr spsr_cxsf, r1 @ Switch to Abort mode (M = 10111)
cps #23
mov lr, r0
mrs r1,cpsr
msr spsr_cxsf, r1 @ Switch to Undefined Instruction Mode (M = 11011)
cps #27
mov lr, r0
mrs r1,cpsr
msr spsr_cxsf, r1 @ Switch to System Mode ( Shares User Mode registers ) (M = 11111)
cps #31
mov lr, r0
mrs r1,cpsr
msr spsr_cxsf, r1
mrc p15, #0x00, r2, c1, c0, #0x02
orr r2, r2, #0xF00000
mcr p15, #0x00, r2, c1, c0, #0x02
mov r2, #0x40000000
fmxr fpexc, r2
fmdrr d0, r1, r1
fmdrr d1, r1, r1
fmdrr d2, r1, r1
fmdrr d3, r1, r1
fmdrr d4, r1, r1
fmdrr d5, r1, r1
fmdrr d6, r1, r1
fmdrr d7, r1, r1
fmdrr d8, r1, r1
fmdrr d9, r1, r1
fmdrr d10, r1, r1
fmdrr d11, r1, r1
fmdrr d12, r1, r1
fmdrr d13, r1, r1
fmdrr d14, r1, r1
fmdrr d15, r1, r1
bl next1
next1:
bl next2
next2:
bl next3
next3:
bl next4
next4:
bx r0
/*-------------------------------------------------------------------------------*/
@ Take CPU to IDLE state
@ SourceId : CORE_SourceId_004
@ DesignId : CORE_DesignId_004
@ Requirements: HL_SR493
.weak _gotoCPUIdle_
.type _gotoCPUIdle_, %function
_gotoCPUIdle_:
WFI
nop
nop
nop
nop
bx lr
/*-------------------------------------------------------------------------------*/
@ Enable VFP Unit
@ SourceId : CORE_SourceId_005
@ DesignId : CORE_DesignId_006
@ Requirements: HL_SR492, HL_SR476
.weak _coreEnableVfp_
.type _coreEnableVfp_, %function
_coreEnableVfp_:
stmfd sp!, {r0}
mrc p15, #0x00, r0, c1, c0, #0x02
orr r0, r0, #0xF00000
mcr p15, #0x00, r0, c1, c0, #0x02
mov r0, #0x40000000
fmxr fpexc, r0
ldmfd sp!, {r0}
bx lr
/*-------------------------------------------------------------------------------*/
@ Enable Event Bus Export
@ SourceId : CORE_SourceId_006
@ DesignId : CORE_DesignId_007
@ Requirements: HL_SR479
.weak _coreEnableEventBusExport_
.type _coreEnableEventBusExport_, %function
_coreEnableEventBusExport_:
stmfd sp!, {r0}
mrc p15, #0x00, r0, c9, c12, #0x00
orr r0, r0, #0x10
mcr p15, #0x00, r0, c9, c12, #0x00
ldmfd sp!, {r0}
bx lr
/*-------------------------------------------------------------------------------*/
@ Disable Event Bus Export
@ SourceId : CORE_SourceId_007
@ DesignId : CORE_DesignId_008
@ Requirements: HL_SR481
.weak _coreDisableEventBusExport_
.type _coreDisableEventBusExport_, %function
_coreDisableEventBusExport_:
stmfd sp!, {r0}
mrc p15, #0x00, r0, c9, c12, #0x00
bic r0, r0, #0x10
mcr p15, #0x00, r0, c9, c12, #0x00
ldmfd sp!, {r0}
bx lr
/*-------------------------------------------------------------------------------*/
@ Enable RAM ECC Support
@ SourceId : CORE_SourceId_008
@ DesignId : CORE_DesignId_009
@ Requirements: HL_SR480
.weak _coreEnableRamEcc_
.type _coreEnableRamEcc_, %function
_coreEnableRamEcc_:
stmfd sp!, {r0}
mrc p15, #0x00, r0, c1, c0, #0x01
orr r0, r0, #0x0C000000
mcr p15, #0x00, r0, c1, c0, #0x01
ldmfd sp!, {r0}
bx lr
/*-------------------------------------------------------------------------------*/
@ Disable RAM ECC Support
@ SourceId : CORE_SourceId_009
@ DesignId : CORE_DesignId_010
@ Requirements: HL_SR482
.weak _coreDisableRamEcc_
.type _coreDisableRamEcc_, %function
_coreDisableRamEcc_:
stmfd sp!, {r0}
mrc p15, #0x00, r0, c1, c0, #0x01
bic r0, r0, #0x0C000000
mcr p15, #0x00, r0, c1, c0, #0x01
ldmfd sp!, {r0}
bx lr
/*-------------------------------------------------------------------------------*/
@ Enable Flash ECC Support
@ SourceId : CORE_SourceId_010
@ DesignId : CORE_DesignId_011
@ Requirements: HL_SR480
.weak _coreEnableFlashEcc_
.type _coreEnableFlashEcc_, %function
_coreEnableFlashEcc_:
stmfd sp!, {r0}
mrc p15, #0x00, r0, c1, c0, #0x01
orr r0, r0, #0x02000000
dmb
mcr p15, #0x00, r0, c1, c0, #0x01
ldmfd sp!, {r0}
bx lr
/*-------------------------------------------------------------------------------*/
@ Disable Flash ECC Support
@ SourceId : CORE_SourceId_011
@ DesignId : CORE_DesignId_012
@ Requirements: HL_SR482
.weak _coreDisableFlashEcc_
.type _coreDisableFlashEcc_, %function
_coreDisableFlashEcc_:
stmfd sp!, {r0}
mrc p15, #0x00, r0, c1, c0, #0x01
bic r0, r0, #0x02000000
mcr p15, #0x00, r0, c1, c0, #0x01
ldmfd sp!, {r0}
bx lr
/*-------------------------------------------------------------------------------*/
@ Enable Offset via Vic controller
@ SourceId : CORE_SourceId_012
@ DesignId : CORE_DesignId_005
@ Requirements: HL_SR483
.weak _coreEnableIrqVicOffset_
.type _coreEnableIrqVicOffset_, %function
_coreEnableIrqVicOffset_:
stmfd sp!, {r0}
mrc p15, #0, r0, c1, c0, #0
orr r0, r0, #0x01000000
mcr p15, #0, r0, c1, c0, #0
ldmfd sp!, {r0}
bx lr
/*-------------------------------------------------------------------------------*/
@ Get data fault status register
@ SourceId : CORE_SourceId_013
@ DesignId : CORE_DesignId_013
@ Requirements: HL_SR495
.weak _coreGetDataFault_
.type _coreGetDataFault_, %function
_coreGetDataFault_:
mrc p15, #0, r0, c5, c0, #0
bx lr
/*-------------------------------------------------------------------------------*/
@ Clear data fault status register
@ SourceId : CORE_SourceId_014
@ DesignId : CORE_DesignId_014
@ Requirements: HL_SR495
.weak _coreClearDataFault_
.type _coreClearDataFault_, %function
_coreClearDataFault_:
stmfd sp!, {r0}
mov r0, #0
mcr p15, #0, r0, c5, c0, #0
ldmfd sp!, {r0}
bx lr
/*-------------------------------------------------------------------------------*/
@ Get instruction fault status register
@ SourceId : CORE_SourceId_015
@ DesignId : CORE_DesignId_015
@ Requirements: HL_SR495
.weak _coreGetInstructionFault_
.type _coreGetInstructionFault_, %function
_coreGetInstructionFault_:
mrc p15, #0, r0, c5, c0, #1
bx lr
/*-------------------------------------------------------------------------------*/
@ Clear instruction fault status register
@ SourceId : CORE_SourceId_016
@ DesignId : CORE_DesignId_016
@ Requirements: HL_SR495
.weak _coreClearInstructionFault_
.type _coreClearInstructionFault_, %function
_coreClearInstructionFault_:
stmfd sp!, {r0}
mov r0, #0
mcr p15, #0, r0, c5, c0, #1
ldmfd sp!, {r0}
bx lr
/*-------------------------------------------------------------------------------*/
@ Get data fault address register
@ SourceId : CORE_SourceId_017
@ DesignId : CORE_DesignId_017
@ Requirements: HL_SR495
.weak _coreGetDataFaultAddress_
.type _coreGetDataFaultAddress_, %function
_coreGetDataFaultAddress_:
mrc p15, #0, r0, c6, c0, #0
bx lr
/*-------------------------------------------------------------------------------*/
@ Clear data fault address register
@ SourceId : CORE_SourceId_018
@ DesignId : CORE_DesignId_018
@ Requirements: HL_SR495
.weak _coreClearDataFaultAddress_
.type _coreClearDataFaultAddress_, %function
_coreClearDataFaultAddress_:
stmfd sp!, {r0}
mov r0, #0
mcr p15, #0, r0, c6, c0, #0
ldmfd sp!, {r0}
bx lr
/*-------------------------------------------------------------------------------*/
@ Get instruction fault address register
@ SourceId : CORE_SourceId_019
@ DesignId : CORE_DesignId_019
@ Requirements: HL_SR495
.weak _coreGetInstructionFaultAddress_
.type _coreGetInstructionFaultAddress_, %function
_coreGetInstructionFaultAddress_:
mrc p15, #0, r0, c6, c0, #2
bx lr
/*-------------------------------------------------------------------------------*/
@ Clear instruction fault address register
@ SourceId : CORE_SourceId_020
@ DesignId : CORE_DesignId_020
@ Requirements: HL_SR495
.weak _coreClearInstructionFaultAddress_
.type _coreClearInstructionFaultAddress_, %function
_coreClearInstructionFaultAddress_:
stmfd sp!, {r0}
mov r0, #0
mcr p15, #0, r0, c6, c0, #2
ldmfd sp!, {r0}
bx lr
/*-------------------------------------------------------------------------------*/
@ Get auxiliary data fault status register
@ SourceId : CORE_SourceId_021
@ DesignId : CORE_DesignId_021
@ Requirements: HL_SR496
.weak _coreGetAuxiliaryDataFault_
.type _coreGetAuxiliaryDataFault_, %function
_coreGetAuxiliaryDataFault_:
mrc p15, #0, r0, c5, c1, #0
bx lr
/*-------------------------------------------------------------------------------*/
@ Clear auxiliary data fault status register
@ SourceId : CORE_SourceId_022
@ DesignId : CORE_DesignId_022
@ Requirements: HL_SR496
.weak _coreClearAuxiliaryDataFault_
.type _coreClearAuxiliaryDataFault_, %function
_coreClearAuxiliaryDataFault_:
stmfd sp!, {r0}
mov r0, #0
mcr p15, #0, r0, c5, c1, #0
ldmfd sp!, {r0}
bx lr
/*-------------------------------------------------------------------------------*/
@ Get auxiliary instruction fault status register
@ SourceId : CORE_SourceId_023
@ DesignId : CORE_DesignId_023
@ Requirements: HL_SR496
.weak _coreGetAuxiliaryInstructionFault_
.type _coreGetAuxiliaryInstructionFault_, %function
_coreGetAuxiliaryInstructionFault_:
mrc p15, #0, r0, c5, c1, #1
bx lr
/*-------------------------------------------------------------------------------*/
@ Clear auxiliary instruction fault status register
@ SourceId : CORE_SourceId_024
@ DesignId : CORE_DesignId_024
@ Requirements: HL_SR496
.weak _coreClearAuxiliaryInstructionFault_
.type _coreClearAuxiliaryInstructionFault_, %function
_coreClearAuxiliaryInstructionFault_:
stmfd sp!, {r0}
mov r0, #0
mrc p15, #0, r0, c5, c1, #1
ldmfd sp!, {r0}
bx lr
/*-------------------------------------------------------------------------------*/
@ Clear ESM CCM errorss
.weak _esmCcmErrorsClear_
.type _esmCcmErrorsClear_, %function
_esmCcmErrorsClear_:
stmfd sp!, {r0-r2}
ldr r0, ESMSR1_REG @ load the ESMSR1 status register address
ldr r2, ESMSR1_ERR_CLR
str r2, [r0] @ clear the ESMSR1 register
ldr r0, ESMSR2_REG @ load the ESMSR2 status register address
ldr r2, ESMSR2_ERR_CLR
str r2, [r0] @ clear the ESMSR2 register
ldr r0, ESMSSR2_REG @ load the ESMSSR2 status register address
ldr r2, ESMSSR2_ERR_CLR
str r2, [r0] @ clear the ESMSSR2 register
ldr r0, ESMKEY_REG @ load the ESMKEY register address
mov r2, #0x5 @ load R2 with 0x5
str r2, [r0] @ clear the ESMKEY register
ldr r0, VIM_INTREQ @ load the INTREQ register address
ldr r2, VIM_INT_CLR
str r2, [r0] @ clear the INTREQ register
ldr r0, CCMR4_STAT_REG @ load the CCMR4 status register address
ldr r2, CCMR4_ERR_CLR
str r2, [r0] @ clear the CCMR4 status register
ldmfd sp!, {r0-r2}
bx lr
ESMSR1_REG: .word 0xFFFFF518
ESMSR2_REG: .word 0xFFFFF51C
ESMSR3_REG: .word 0xFFFFF520
ESMKEY_REG: .word 0xFFFFF538
ESMSSR2_REG: .word 0xFFFFF53C
CCMR4_STAT_REG: .word 0xFFFFF600
ERR_CLR_WRD: .word 0xFFFFFFFF
CCMR4_ERR_CLR: .word 0x00010000
ESMSR1_ERR_CLR: .word 0x80000000
ESMSR2_ERR_CLR: .word 0x00000004
ESMSSR2_ERR_CLR: .word 0x00000004
VIM_INT_CLR: .word 0x00000001
VIM_INTREQ: .word 0xFFFFFE20
#if 1/*-------------------------------------------------------------------------------*/
@ Work Around for Errata CORTEX-R4#57:
@
@ Errata Description:
@ Conditional VMRS APSR_Nzcv, FPSCR May Evaluate With Incorrect Flags
@ Workaround:
@ Disable out-of-order single-precision floating point
@ multiply-accumulate instruction completion
.weak _errata_CORTEXR4_57_
.type _errata_CORTEXR4_57_, %function
_errata_CORTEXR4_57_:
push {r0}
mrc p15, #0, r0, c15, c0, #0 @ Read Secondary Auxiliary Control Register
orr r0, r0, #0x10000 @ Set BIT 16 (Set DOOFMACS)
mcr p15, #0, r0, c15, c0, #0 @ Write Secondary Auxiliary Control Register
pop {r0}
bx lr
#endif
/*-------------------------------------------------------------------------------*/
@ Work Around for Errata CORTEX-R4#66:
@
@ Errata Description:
@ Register Corruption During A Load-Multiple Instruction At
@ an Exception Vector
@ Workaround:
@ Disable out-of-order completion for divide instructions in
@ Auxiliary Control register
.weak _errata_CORTEXR4_66_
.type _errata_CORTEXR4_66_, %function
_errata_CORTEXR4_66_:
push {r0}
mrc p15, #0, r0, c1, c0, #1 @ Read Auxiliary Control register
orr r0, r0, #0x80 @ Set BIT 7 (Disable out-of-order completion
@ for divide instructions.)
mcr p15, #0, r0, c1, c0, #1 @ Write Auxiliary Control register
pop {r0}
bx lr
/*-------------------------------------------------------------------------------*/

View File

@@ -0,0 +1,185 @@
/**
* @file tms570_tcram_tests.c
*
* @ingroup tms570
*
* @brief TCRAM selftest function.
*/
/*
* Copyright (c) 2016 Pavel Pisa <pisa@cmp.felk.cvut.cz>
*
* Czech Technical University in Prague
* Zikova 1903/4
* 166 36 Praha 6
* Czech Republic
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
*
* Algorithms are based on Ti manuals and Ti HalCoGen generated
* code available under following copyright.
*/
/*
* Copyright (C) 2009-2015 Texas Instruments Incorporated - 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 <bsp/tms570.h>
#include "tms570_selftest.h"
#include "tms570_hwinit.h"
#define tcramA1bitError (*(volatile uint32_t *)(0x08400000U))
#define tcramA2bitError (*(volatile uint32_t *)(0x08400010U))
#define tcramB1bitError (*(volatile uint32_t *)(0x08400008U))
#define tcramB2bitError (*(volatile uint32_t *)(0x08400018U))
#define tcramA1bit (*(volatile uint64_t *)(0x08000000U))
#define tcramA2bit (*(volatile uint64_t *)(0x08000010U))
#define tcramB1bit (*(volatile uint64_t *)(0x08000008U))
#define tcramB2bit (*(volatile uint64_t *)(0x08000018U))
/**
* @brief Check TCRAM ECC error detection logic (HCG:checkRAMECC)
*
* This function checks TCRAM ECC error detection and correction logic.
* The function does not return in case of TCRAM error.
* It calls bsp_selftest_fail_notification() instead.
*
*/
/* SourceId : SELFTEST_SourceId_034 */
/* DesignId : SELFTEST_DesignId_019 */
/* Requirements : HL_SR408 */
void tms570_check_tcram_ecc( void )
{
volatile uint64_t ramread;
volatile uint32_t regread;
uint32_t tcram1ErrStat, tcram2ErrStat = 0U;
uint64_t tcramA1_bk = tcramA1bit;
uint64_t tcramB1_bk = tcramB1bit;
uint64_t tcramA2_bk = tcramA2bit;
uint64_t tcramB2_bk = tcramB2bit;
/* Clear RAMOCUUR before setting RAMTHRESHOLD register */
TMS570_TCRAM1.RAMOCCUR = 0U;
TMS570_TCRAM2.RAMOCCUR = 0U;
/* Set Single-bit Error Threshold Count as 1 */
TMS570_TCRAM1.RAMTHRESHOLD = 1U;
TMS570_TCRAM2.RAMTHRESHOLD = 1U;
/* Enable single bit error generation */
TMS570_TCRAM1.RAMINTCTRL = 1U;
TMS570_TCRAM2.RAMINTCTRL = 1U;
/* Enable writes to ECC RAM, enable ECC error response */
TMS570_TCRAM1.RAMCTRL = 0x0005010AU;
TMS570_TCRAM2.RAMCTRL = 0x0005010AU;
/* Force a single bit error in both the banks */
_coreDisableRamEcc_();
tcramA1bitError ^= 1U;
tcramB1bitError ^= 1U;
_coreEnableRamEcc_();
/* Read the corrupted data to generate single bit error */
ramread = tcramA1bit;
ramread = tcramB1bit;
(void)ramread;
/* Check for error status */
tcram1ErrStat = TMS570_TCRAM1.RAMERRSTATUS & 0x1U;
tcram2ErrStat = TMS570_TCRAM2.RAMERRSTATUS & 0x1U;
/*SAFETYMCUSW 139 S MR:13.7 <APPROVED> "LDRA Tool issue" */
/*SAFETYMCUSW 139 S MR:13.7 <APPROVED> "LDRA Tool issue" */
if ((tcram1ErrStat == 0U) || (tcram2ErrStat == 0U)) {
/* TCRAM module does not reflect 1-bit error reported by CPU */
bsp_selftest_fail_notification(CHECKRAMECC_FAIL1);
} else {
if (!tms570_esm_channel_sr_get(1, 26) || !tms570_esm_channel_sr_get(1, 28)) {
/* TCRAM 1-bit error not flagged in ESM */
bsp_selftest_fail_notification(CHECKRAMECC_FAIL2);
} else {
/* Clear single bit error flag in TCRAM module */
TMS570_TCRAM1.RAMERRSTATUS = 0x1U;
TMS570_TCRAM2.RAMERRSTATUS = 0x1U;
/* Clear ESM status */
tms570_esm_channel_sr_clear(1, 26);
tms570_esm_channel_sr_clear(1, 28);
}
}
#if 0
/*
* This test sequence requires that data abort exception
* handler checks for ECC test write enable in RAMCTR (bit 8)
* and if the access abort is intended then it should clear
* error status TCRAM status register and checks and clears
* ESM group3 uncorrectable TCRAM error channels.
*
* More modifications in BSP and RTEMS ARM support are
* required to make this code work.
*/
/* Force a double bit error in both the banks */
_coreDisableRamEcc_();
tcramA2bitError ^= 3U;
tcramB2bitError ^= 3U;
_coreEnableRamEcc_();
/* Read the corrupted data to generate double bit error */
ramread = tcramA2bit;
ramread = tcramB2bit;
/* read from location with 2-bit ECC error this will cause a data abort to be generated */
/* See HalCoGen support src/sys/asm/dabort.asm */
/* _ARMV4_Exception_data_abort_default has to include solution for this special case for RTEMS */
#endif
regread = TMS570_TCRAM1.RAMUERRADDR;
regread = TMS570_TCRAM2.RAMUERRADDR;
(void)regread;
/* disable writes to ECC RAM */
TMS570_TCRAM1.RAMCTRL = 0x0005000AU;
TMS570_TCRAM2.RAMCTRL = 0x0005000AU;
/* Compute correct ECC */
tcramA1bit = tcramA1_bk;
tcramB1bit = tcramB1_bk;
tcramA2bit = tcramA2_bk;
tcramB2bit = tcramB2_bk;
}