mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2025-06-17 17:59:03 -04:00
409 lines
16 KiB
C
409 lines
16 KiB
C
/***********************************************************************************************************************
|
|
* DISCLAIMER
|
|
* This software is supplied by Renesas Electronics Corporation and is only intended for use with Renesas products. No
|
|
* other uses are authorized. This software is owned by Renesas Electronics Corporation and is protected under all
|
|
* applicable laws, including copyright laws.
|
|
* THIS SOFTWARE IS PROVIDED "AS IS" AND RENESAS MAKES NO WARRANTIES REGARDING
|
|
* THIS SOFTWARE, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY,
|
|
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. ALL SUCH WARRANTIES ARE EXPRESSLY DISCLAIMED. TO THE MAXIMUM
|
|
* EXTENT PERMITTED NOT PROHIBITED BY LAW, NEITHER RENESAS ELECTRONICS CORPORATION NOR ANY OF ITS AFFILIATED COMPANIES
|
|
* SHALL BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES FOR ANY REASON RELATED TO THIS
|
|
* SOFTWARE, EVEN IF RENESAS OR ITS AFFILIATES HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
|
|
* Renesas reserves the right, without notice, to make changes to this software and to discontinue the availability of
|
|
* this software. By using this software, you agree to the additional terms and conditions found by accessing the
|
|
* following link:
|
|
* http://www.renesas.com/disclaimer
|
|
*
|
|
* Copyright (C) 2012 Renesas Electronics Corporation. All rights reserved.
|
|
***********************************************************************************************************************/
|
|
/***********************************************************************************************************************
|
|
* File Name : resetprg.c
|
|
* Device(s) : RX63x
|
|
* Description : Defines post-reset routines that are used to configure the MCU prior to the main program starting.
|
|
* This is were the program counter starts on power-up or reset.
|
|
***********************************************************************************************************************/
|
|
/***********************************************************************************************************************
|
|
* History : DD.MM.YYYY Version Description
|
|
* : 26.10.2011 1.00 First Release
|
|
* : 13.03.2012 1.10 Stack sizes are now defined in r_bsp_config.h. Because of this the #include for
|
|
* stacksct.h was removed. Settings for SCKCR are now set in r_bsp_config.h and used here
|
|
* to setup clocks based on user settings.
|
|
***********************************************************************************************************************/
|
|
|
|
/***********************************************************************************************************************
|
|
Includes <System Includes> , "Project Includes"
|
|
***********************************************************************************************************************/
|
|
/* Defines machine level functions used in this file */
|
|
#include <machine.h>
|
|
/* Defines MCU configuration functions used in this file */
|
|
#include <_h_c_lib.h>
|
|
/* Defines standard variable types used in this file */
|
|
#include <stdbool.h>
|
|
#include <stdint.h>
|
|
|
|
/* This macro is here so that the stack will be declared here. This is used to prevent multiplication of stack size. */
|
|
#define BSP_DECLARE_STACK
|
|
/* Define the target platform */
|
|
#include "platform.h"
|
|
|
|
/***********************************************************************************************************************
|
|
Macro definitions
|
|
***********************************************************************************************************************/
|
|
#define PSW_init (0x00030000)
|
|
#define FPSW_init (0x00000100)
|
|
|
|
/***********************************************************************************************************************
|
|
Pre-processor Directives
|
|
***********************************************************************************************************************/
|
|
/* Declare the contents of the function 'Change_PSW_PM_to_UserMode' as
|
|
assembler to the compiler */
|
|
#pragma inline_asm Change_PSW_PM_to_UserMode
|
|
|
|
/* Set this as the entry point from a power-on reset */
|
|
#pragma entry PowerON_Reset_PC
|
|
|
|
/***********************************************************************************************************************
|
|
External function Prototypes
|
|
***********************************************************************************************************************/
|
|
/* Functions to setup I/O library */
|
|
extern void _INIT_IOLIB(void);
|
|
extern void _CLOSEALL(void);
|
|
|
|
/***********************************************************************************************************************
|
|
Private global variables and functions
|
|
***********************************************************************************************************************/
|
|
/* Power-on reset function declaration */
|
|
void PowerON_Reset_PC(void);
|
|
|
|
#if RUN_IN_USER_MODE==1
|
|
#if __RENESAS_VERSION__ < 0x01010000
|
|
/* MCU usermode switcher function declaration */
|
|
static void Change_PSW_PM_to_UserMode(void);
|
|
#endif
|
|
#endif
|
|
|
|
/* Main program function delcaration */
|
|
void main(void);
|
|
static void operating_frequency_set(void);
|
|
|
|
/***********************************************************************************************************************
|
|
* Function name: PowerON_Reset_PC
|
|
* Description : This function is the MCU's entry point from a power-on reset.
|
|
* The following steps are taken in the startup code:
|
|
* 1. The User Stack Pointer (USP) and Interrupt Stack Pointer (ISP) are both set immediately after entry
|
|
* to this function. The USP and ISP stack sizes are set in the file stacksct.h.
|
|
* Default sizes are USP=4K and ISP=1K.
|
|
* 2. The interrupt vector base register is set to point to the beginning of the relocatable interrupt
|
|
* vector table.
|
|
* 3. The MCU is setup for floating point operations by setting the initial value of the Floating Point
|
|
* Status Word (FPSW).
|
|
* 4. The MCU operating frequency is set by configuring the Clock Generation Circuit (CGC) in
|
|
* operating_frequency_set.
|
|
* 5. Calls are made to functions to setup the C runtime environment which involves initializing all
|
|
* initialed data, zeroing all uninitialized variables, and configuring STDIO if used
|
|
* (calls to _INITSCT and _INIT_IOLIB).
|
|
* 6. Board-specific hardware setup, including configuring I/O pins on the MCU, in hardware_setup.
|
|
* 7. Global interrupts are enabled by setting the I bit in the Program Status Word (PSW), and the stack
|
|
* is switched from the ISP to the USP. The initial Interrupt Priority Level is set to zero, enabling
|
|
* any interrupts with a priority greater than zero to be serviced.
|
|
* 8. The processor is optionally switched to user mode. To run in user mode, set the macro
|
|
* RUN_IN_USER_MODE above to a 1.
|
|
* 9. The bus error interrupt is enabled to catch any accesses to invalid or reserved areas of memory.
|
|
*
|
|
* Once this initialization is complete, the user's main() function is called. It should not return.
|
|
* Arguments : none
|
|
* Return value : none
|
|
***********************************************************************************************************************/
|
|
void PowerON_Reset_PC(void)
|
|
{
|
|
/* Stack pointers are setup prior to calling this function - see comments above */
|
|
|
|
/* Initialise the MCU processor word */
|
|
#if __RENESAS_VERSION__ >= 0x01010000
|
|
set_intb((void *)__sectop("C$VECT"));
|
|
#else
|
|
set_intb((unsigned long)__sectop("C$VECT"));
|
|
#endif
|
|
|
|
/* Initialize FPSW for floating-point operations */
|
|
#ifdef __ROZ
|
|
#define _ROUND 0x00000001 /* Let FPSW RMbits=01 (round to zero) */
|
|
#else
|
|
#define _ROUND 0x00000000 /* Let FPSW RMbits=00 (round to nearest) */
|
|
#endif
|
|
#ifdef __DOFF
|
|
#define _DENOM 0x00000100 /* Let FPSW DNbit=1 (denormal as zero) */
|
|
#else
|
|
#define _DENOM 0x00000000 /* Let FPSW DNbit=0 (denormal as is) */
|
|
#endif
|
|
set_fpsw(FPSW_init | _ROUND | _DENOM);
|
|
|
|
/* Switch to high-speed operation */
|
|
operating_frequency_set();
|
|
|
|
/* Initialize C runtime environment */
|
|
_INITSCT();
|
|
|
|
/* Comment this out if not using I/O lib */
|
|
_INIT_IOLIB();
|
|
|
|
/* Configure the MCU and YRDK hardware */
|
|
hardware_setup();
|
|
|
|
/* Change the MCU's usermode from supervisor to user */
|
|
nop();
|
|
set_psw(PSW_init);
|
|
#if RUN_IN_USER_MODE==1
|
|
/* Use chg_pmusr() intrinsic if possible. */
|
|
#if __RENESAS_VERSION__ >= 0x01010000
|
|
chg_pmusr() ;
|
|
#else
|
|
Change_PSW_PM_to_UserMode();
|
|
#endif
|
|
#endif
|
|
|
|
|
|
/* Enable the bus error interrupt to catch accesses to illegal/reserved areas of memory */
|
|
/* The ISR for this interrupt can be found in vecttbl.c in the function "bus_error_isr" */
|
|
/* Clear any pending interrupts */
|
|
IR(BSC,BUSERR) = 0;
|
|
/* Make this the highest priority interrupt (adjust as necessary for your application */
|
|
IPR(BSC,BUSERR) = 0x0F;
|
|
/* Enable the interrupt in the ICU*/
|
|
IEN(BSC,BUSERR) = 1;
|
|
/* Enable illegal address interrupt in the BSC */
|
|
BSC.BEREN.BIT.IGAEN = 1;
|
|
|
|
/* Call the main program function (should not return) */
|
|
main();
|
|
|
|
/* Comment this out if not using I/O lib - cleans up open files */
|
|
_CLOSEALL();
|
|
|
|
while(1)
|
|
{
|
|
/* Infinite loop. Put a breakpoint here if you want to catch an exit of main(). */
|
|
}
|
|
}
|
|
|
|
/***********************************************************************************************************************
|
|
* Function name: operating_frequency_set
|
|
* Description : Configures the clock settings for each of the device clocks
|
|
* Arguments : none
|
|
* Return value : none
|
|
***********************************************************************************************************************/
|
|
void operating_frequency_set(void)
|
|
{
|
|
/* Used for constructing value to write to SCKCR register. */
|
|
uint32_t temp_clock = 0;
|
|
|
|
/*
|
|
Clock Description Frequency
|
|
----------------------------------------
|
|
Input Clock Frequency............ 12 MHz
|
|
PLL frequency (x16).............. 192 MHz
|
|
Internal Clock Frequency......... 96 MHz
|
|
Peripheral Clock Frequency....... 48 MHz
|
|
USB Clock Frequency.............. 48 MHz
|
|
External Bus Clock Frequency..... 24 MHz */
|
|
|
|
volatile unsigned int i;
|
|
|
|
/* Protect off. */
|
|
SYSTEM.PRCR.WORD = 0xA50B;
|
|
|
|
/* Uncomment if not using sub-clock */
|
|
//SYSTEM.SOSCCR.BYTE = 0x01; /* stop sub-clock */
|
|
SYSTEM.SOSCCR.BYTE = 0x00; /* Enable sub-clock for RTC */
|
|
|
|
/* Wait 131,072 cycles * 12 MHz = 10.9 ms */
|
|
SYSTEM.MOSCWTCR.BYTE = 0x0D;
|
|
|
|
/* PLL wait is 4,194,304 cycles (default) * 192 MHz (12 MHz * 16) = 20.1 ms*/
|
|
SYSTEM.PLLWTCR.BYTE = 0x0F;
|
|
|
|
/* Set PLL Input Divisor. */
|
|
SYSTEM.PLLCR.BIT.PLIDIV = PLL_DIV >> 1;
|
|
|
|
/* Set PLL Multiplier. */
|
|
SYSTEM.PLLCR.BIT.STC = PLL_MUL - 1;
|
|
|
|
/* EXTAL ON */
|
|
SYSTEM.MOSCCR.BYTE = 0x00;
|
|
|
|
/* PLL ON */
|
|
SYSTEM.PLLCR2.BYTE = 0x00;
|
|
|
|
for(i = 0;i< 0x168;i++)
|
|
{
|
|
/* Wait over 12ms */
|
|
nop() ;
|
|
}
|
|
|
|
/* Figure out setting for FCK bits. */
|
|
#if FCK_DIV == 1
|
|
/* Do nothing since FCK bits should be 0. */
|
|
#elif FCK_DIV == 2
|
|
temp_clock |= 0x10000000;
|
|
#elif FCK_DIV == 4
|
|
temp_clock |= 0x20000000;
|
|
#elif FCK_DIV == 8
|
|
temp_clock |= 0x30000000;
|
|
#elif FCK_DIV == 16
|
|
temp_clock |= 0x40000000;
|
|
#elif FCK_DIV == 32
|
|
temp_clock |= 0x50000000;
|
|
#elif FCK_DIV == 64
|
|
temp_clock |= 0x60000000;
|
|
#else
|
|
#error "Error! Invalid setting for FCK_DIV in r_bsp_config.h"
|
|
#endif
|
|
|
|
/* Figure out setting for ICK bits. */
|
|
#if ICK_DIV == 1
|
|
/* Do nothing since ICK bits should be 0. */
|
|
#elif ICK_DIV == 2
|
|
temp_clock |= 0x01000000;
|
|
#elif ICK_DIV == 4
|
|
temp_clock |= 0x02000000;
|
|
#elif ICK_DIV == 8
|
|
temp_clock |= 0x03000000;
|
|
#elif ICK_DIV == 16
|
|
temp_clock |= 0x04000000;
|
|
#elif ICK_DIV == 32
|
|
temp_clock |= 0x05000000;
|
|
#elif ICK_DIV == 64
|
|
temp_clock |= 0x06000000;
|
|
#else
|
|
#error "Error! Invalid setting for ICK_DIV in r_bsp_config.h"
|
|
#endif
|
|
|
|
/* SDCLK Pin Output and BCLK Pin Output are disabled by default. */
|
|
temp_clock |= 0x00C00000;
|
|
|
|
/* Figure out setting for BCK bits. */
|
|
#if BCK_DIV == 1
|
|
/* Do nothing since BCK bits should be 0. */
|
|
#elif BCK_DIV == 2
|
|
temp_clock |= 0x00010000;
|
|
#elif BCK_DIV == 4
|
|
temp_clock |= 0x00020000;
|
|
#elif BCK_DIV == 8
|
|
temp_clock |= 0x00030000;
|
|
#elif BCK_DIV == 16
|
|
temp_clock |= 0x00040000;
|
|
#elif BCK_DIV == 32
|
|
temp_clock |= 0x00050000;
|
|
#elif BCK_DIV == 64
|
|
temp_clock |= 0x00060000;
|
|
#else
|
|
#error "Error! Invalid setting for BCK_DIV in r_bsp_config.h"
|
|
#endif
|
|
|
|
/* Figure out setting for PCKA bits. */
|
|
#if PCKA_DIV == 1
|
|
/* Do nothing since PCKA bits should be 0. */
|
|
#elif PCKA_DIV == 2
|
|
temp_clock |= 0x00001000;
|
|
#elif PCKA_DIV == 4
|
|
temp_clock |= 0x00002000;
|
|
#elif PCKA_DIV == 8
|
|
temp_clock |= 0x00003000;
|
|
#elif PCKA_DIV == 16
|
|
temp_clock |= 0x00004000;
|
|
#elif PCKA_DIV == 32
|
|
temp_clock |= 0x00005000;
|
|
#elif PCKA_DIV == 64
|
|
temp_clock |= 0x00006000;
|
|
#else
|
|
#error "Error! Invalid setting for PCKA_DIV in r_bsp_config.h"
|
|
#endif
|
|
|
|
/* Figure out setting for PCKB bits. */
|
|
#if PCKB_DIV == 1
|
|
/* Do nothing since PCKB bits should be 0. */
|
|
#elif PCKB_DIV == 2
|
|
temp_clock |= 0x00000100;
|
|
#elif PCKB_DIV == 4
|
|
temp_clock |= 0x00000200;
|
|
#elif PCKB_DIV == 8
|
|
temp_clock |= 0x00000300;
|
|
#elif PCKB_DIV == 16
|
|
temp_clock |= 0x00000400;
|
|
#elif PCKB_DIV == 32
|
|
temp_clock |= 0x00000500;
|
|
#elif PCKB_DIV == 64
|
|
temp_clock |= 0x00000600;
|
|
#else
|
|
#error "Error! Invalid setting for PCKB_DIV in r_bsp_config.h"
|
|
#endif
|
|
|
|
/* Bottom byte of SCKCR register must be set to 0x11 */
|
|
temp_clock |= 0x00000011;
|
|
|
|
/* Set SCKCR register. */
|
|
SYSTEM.SCKCR.LONG = temp_clock;
|
|
|
|
/* Re-init temp_clock to use to set SCKCR2. */
|
|
temp_clock = 0;
|
|
|
|
/* Figure out setting for IEBCK bits. */
|
|
#if IEBCK_DIV == 2
|
|
temp_clock |= 0x00000001;
|
|
#elif IEBCK_DIV == 4
|
|
temp_clock |= 0x00000002;
|
|
#elif IEBCK_DIV == 6
|
|
temp_clock |= 0x0000000C;
|
|
#elif IEBCK_DIV == 8
|
|
temp_clock |= 0x00000003;
|
|
#elif IEBCK_DIV == 16
|
|
temp_clock |= 0x00000004;
|
|
#elif IEBCK_DIV == 32
|
|
temp_clock |= 0x00000005;
|
|
#elif IEBCK_DIV == 64
|
|
temp_clock |= 0x00000006;
|
|
#else
|
|
#error "Error! Invalid setting for IEBCK_DIV in r_bsp_config.h"
|
|
#endif
|
|
|
|
/* Figure out setting for UCK bits. */
|
|
#if UCK_DIV == 3
|
|
temp_clock |= 0x00000020;
|
|
#elif UCK_DIV == 4
|
|
temp_clock |= 0x00000030;
|
|
#else
|
|
#error "Error! Invalid setting for UCK_DIV in r_bsp_config.h"
|
|
#endif
|
|
|
|
/* Set SCKCR2 register. */
|
|
SYSTEM.SCKCR2.WORD = (uint16_t)temp_clock;
|
|
|
|
/* Choose clock source. Default for r_bsp_config.h is PLL. */
|
|
SYSTEM.SCKCR3.WORD = ((uint16_t)CLOCK_SOURCE) << 8;
|
|
|
|
/* Protect on. */
|
|
SYSTEM.PRCR.WORD = 0xA500;
|
|
}
|
|
|
|
/***********************************************************************************************************************
|
|
* Function name: Change_PSW_PM_to_UserMode
|
|
* Description : Assembler function, used to change the MCU's usermode from supervisor to user.
|
|
* Arguments : none
|
|
* Return value : none
|
|
***********************************************************************************************************************/
|
|
#if RUN_IN_USER_MODE==1
|
|
#if __RENESAS_VERSION__ < 0x01010000
|
|
static void Change_PSW_PM_to_UserMode(void)
|
|
{
|
|
MVFC PSW,R1
|
|
OR #00100000h,R1
|
|
PUSH.L R1
|
|
MVFC PC,R1
|
|
ADD #10,R1
|
|
PUSH.L R1
|
|
RTE
|
|
NOP
|
|
NOP
|
|
}
|
|
#endif
|
|
#endif |