| /***********************************************************************************************************************
|
| * 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 |