r_bsp_common.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. /***********************************************************************************************************************
  2. * DISCLAIMER
  3. * This software is supplied by Renesas Electronics Corporation and is only intended for use with Renesas products. No
  4. * other uses are authorized. This software is owned by Renesas Electronics Corporation and is protected under all
  5. * applicable laws, including copyright laws.
  6. * THIS SOFTWARE IS PROVIDED "AS IS" AND RENESAS MAKES NO WARRANTIES REGARDING
  7. * THIS SOFTWARE, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY,
  8. * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. ALL SUCH WARRANTIES ARE EXPRESSLY DISCLAIMED. TO THE MAXIMUM
  9. * EXTENT PERMITTED NOT PROHIBITED BY LAW, NEITHER RENESAS ELECTRONICS CORPORATION NOR ANY OF ITS AFFILIATED COMPANIES
  10. * SHALL BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES FOR ANY REASON RELATED TO THIS
  11. * SOFTWARE, EVEN IF RENESAS OR ITS AFFILIATES HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
  12. * Renesas reserves the right, without notice, to make changes to this software and to discontinue the availability of
  13. * this software. By using this software, you agree to the additional terms and conditions found by accessing the
  14. * following link:
  15. * http://www.renesas.com/disclaimer
  16. *
  17. * Copyright (C) 2013 Renesas Electronics Corporation. All rights reserved.
  18. ***********************************************************************************************************************/
  19. /***********************************************************************************************************************
  20. * File Name : r_bsp_common.c
  21. * Description : Implements functions that apply to all r_bsp boards and MCUs.
  22. ***********************************************************************************************************************/
  23. /**********************************************************************************************************************
  24. * History : DD.MM.YYYY Version Description
  25. * : 06.05.2013 1.00 First Release
  26. * : 26.03.2014 1.10 Added R_BSP_SoftwareDelay() function
  27. * : 03.09.2014 1.20 Corrected R_BSP_SoftwareDelay() timing when using an RX64M
  28. * : 30.09.2015 1.30 Added RX23T
  29. * : 01.02.2016 1.40 Added RX24T
  30. * Changed the value of the following macro definition.
  31. * - OVERHEAD_CYCLES
  32. * - OVERHEAD_CYCLES_64
  33. * : 29.02.2016 1.50 Added RX230
  34. * : 01.10.2016 1.60 Added RX65N
  35. * : 22.08.2016 1.70 Added RX24U
  36. * : 15.05.2017 1.80 Changed method of selecting the number of CPU cycles required to execute
  37. * the delayWait() loop.
  38. * : xx.xx.xxxx 1.90 Added support for GNUC and ICCRX.
  39. ***********************************************************************************************************************/
  40. /***********************************************************************************************************************
  41. Includes <System Includes> , "Project Includes"
  42. ***********************************************************************************************************************/
  43. /* Get information about current board and MCU. */
  44. #include "platform.h"
  45. /***********************************************************************************************************************
  46. Macro definitions
  47. ***********************************************************************************************************************/
  48. #define OVERHEAD_CYCLES (2) // R_BSP_SoftwareDelay() overhead per call
  49. #define OVERHEAD_CYCLES_64 (2) // R_BSP_SoftwareDelay() overhead per call using 64-bit ints
  50. #define CKSEL_LOCO (0x0) // SCKCR3 register setting for LOCO
  51. /***********************************************************************************************************************
  52. Typedef definitions
  53. ***********************************************************************************************************************/
  54. /***********************************************************************************************************************
  55. Exported global variables (to be accessed by other files)
  56. ***********************************************************************************************************************/
  57. /***********************************************************************************************************************
  58. Private global variables and functions
  59. ***********************************************************************************************************************/
  60. extern uint32_t get_iclk_freq_hz(void); // Get the board specific ICLK frequency
  61. /***********************************************************************************************************************
  62. * Function Name: R_BSP_GetVersion
  63. * Description : Returns the current version of this module. The version number is encoded where the top 2 bytes are the
  64. * major version number and the bottom 2 bytes are the minor version number. For example, Version 4.25
  65. * would be returned as 0x00040019.
  66. * Arguments : none
  67. * Return Value : Version of this module.
  68. ***********************************************************************************************************************/
  69. R_PRAGMA_INLINE(R_BSP_GetVersion) uint32_t R_BSP_GetVersion (void)
  70. {
  71. /* These version macros are defined in platform.h. */
  72. return ((((uint32_t)R_BSP_VERSION_MAJOR) << 16) | (uint32_t)R_BSP_VERSION_MINOR);
  73. }
  74. /***********************************************************************************************************************
  75. * Function Name: delayWait
  76. * Description : This asm loop executes a known number (5) of CPU cycles. If a value of '4' is passed
  77. * in as an argument, then this function would consume 20 CPU cycles before returning.
  78. * Arguments : loop_cnt - A single 32-bit value is provided as the number of loops to execute.
  79. * :
  80. * Return Value : None
  81. ***********************************************************************************************************************/
  82. R_PRAGMA_STATIC_INLINE_ASM(delayWait)
  83. void delayWait (unsigned long loop_cnt)
  84. {
  85. R_ASM_INTERNAL_USED(loop_cnt)
  86. R_ASM_BEGIN
  87. R_ASM( BRA.B R_LAB_NEXT(0) )
  88. R_ASM( NOP ) // FIXME: What is the purpose of this NOP?
  89. R_LAB(0: )
  90. R_ASM( NOP )
  91. R_ASM( SUB #01H, R1 )
  92. R_ASM( BNE.B R_LAB_PREV(0) )
  93. R_ASM_END
  94. }
  95. /***********************************************************************************************************************
  96. * Function Name: R_BSP_GetIClkFreqHz
  97. * Description : Return the current ICLK frequency in Hz.
  98. * Arguments : None
  99. * Return Value : uint32_t - the system ICLK frequency in Hz
  100. ***********************************************************************************************************************/
  101. uint32_t R_BSP_GetIClkFreqHz(void)
  102. {
  103. return get_iclk_freq_hz(); // Get the MCU specific ICLK frequency
  104. }
  105. /***********************************************************************************************************************
  106. * Function Name: R_BSP_SoftwareDelay
  107. * Description : Delay the specified duration in units and return.
  108. * Arguments : uint32_t delay - the number of 'units' to delay
  109. * : bsp_delay_units_t units - the 'base' for the units specified. Valid values are:
  110. * BSP_DELAY_MICROSECS, BSP_DELAY_MILLISECS, BSP_DELAY_SECS.
  111. *
  112. * Accuracy is good, however the minimum possible delay depends on the current ICLK frequency
  113. * and the overhead clock cycles required for this function to run.
  114. * For example, given a 16 MHz ICLK and 180 clock cycles for this function, the minimum
  115. * possible delay would be: 1/16000000 * 180 = 11.25 uS
  116. *
  117. * Return Value : true if delay executed.
  118. * false if delay/units combination resulted in overflow or the delay cannot be achieved
  119. ***********************************************************************************************************************/
  120. bool R_BSP_SoftwareDelay(uint32_t delay, bsp_delay_units_t units)
  121. {
  122. volatile uint32_t iclkRate;
  123. volatile uint32_t delay_cycles;
  124. volatile uint32_t loop_cnt;
  125. volatile uint64_t delay_cycles_64;
  126. volatile uint64_t loop_cnt_64;
  127. #ifdef BSP_CFG_PARAM_CHECKING_ENABLE
  128. if ((units != BSP_DELAY_MICROSECS) && (units != BSP_DELAY_MILLISECS) && (units != BSP_DELAY_SECS))
  129. {
  130. return(false);
  131. }
  132. #endif
  133. iclkRate = R_BSP_GetIClkFreqHz(); // Get the current ICLK frequency
  134. /*
  135. * In order to handle all possible combinations of delay/ICLK it is necessary to use 64-bit
  136. * integers (not all MCUs have floating point support). However, there is no native hw support
  137. * for 64 bit integers so it requires many more clock cycles. This is not an issue if the
  138. * requested delay is long enough and the ICLK is fast, but for delays in the low microseconds
  139. * and/or a slow ICLK we use 32 bit integers to reduce the overhead cycles of this function
  140. * by approximately a third and stand the best chance of achieving the requested delay.
  141. */
  142. if ( (units == BSP_DELAY_MICROSECS) &&
  143. (delay <= (0xFFFFFFFFUL / iclkRate)) ) // Ensure (iclkRate * delay) will not exceed 32 bits
  144. {
  145. delay_cycles = ((iclkRate * delay) / units);
  146. if (delay_cycles > OVERHEAD_CYCLES)
  147. {
  148. delay_cycles -= OVERHEAD_CYCLES;
  149. }
  150. else
  151. {
  152. delay_cycles = 0;
  153. }
  154. loop_cnt = delay_cycles / CPU_CYCLES_PER_LOOP;
  155. if (loop_cnt == 0)
  156. {
  157. /* The requested delay is too large/small for the current ICLK. Return false which
  158. * also results in the minimum possible delay. */
  159. return(false);
  160. }
  161. }
  162. else
  163. {
  164. delay_cycles_64 = (((uint64_t)iclkRate * (uint64_t)delay) / units);
  165. if (delay_cycles_64 > OVERHEAD_CYCLES_64)
  166. {
  167. delay_cycles_64 -= OVERHEAD_CYCLES_64;
  168. }
  169. else
  170. {
  171. delay_cycles = 0;
  172. }
  173. loop_cnt_64 = delay_cycles_64 / CPU_CYCLES_PER_LOOP;
  174. if ((loop_cnt_64 > 0xFFFFFFFF) || (loop_cnt_64 == 0))
  175. {
  176. /* The requested delay is too large/small for the current ICLK. Return false which
  177. * also results in the minimum possible delay. */
  178. return(false);
  179. }
  180. loop_cnt = (uint32_t)loop_cnt_64;
  181. }
  182. delayWait(loop_cnt);
  183. return(true);
  184. }
  185. /***********************************************************************************************************************
  186. * Function name: R_BSP_Change_PSW_PM_to_UserMode
  187. * Description : Switches to user mode. The PSW will be changed as following.
  188. * Before Execution After Execution
  189. * PSW.PM PSW.U PSW.PM PSW.U
  190. * 0 (supervisor mode) 0 (interrupt stack) --> 1 (user mode) 1 (user stack)
  191. * 0 (supervisor mode) 1 (user stack) --> 1 (user mode) 1 (user stack)
  192. * 1 (user mode) 1 (user stack) --> NO CHANGE
  193. * 1 (user mode) 0 (interrupt stack)) <== N/A
  194. * Arguments : none
  195. * Return value : none
  196. ***********************************************************************************************************************/
  197. R_PRAGMA_INLINE_ASM(R_BSP_Change_PSW_PM_to_UserMode)
  198. void R_BSP_Change_PSW_PM_to_UserMode(void)
  199. {
  200. R_ASM_BEGIN
  201. R_ASM(;_R_BSP_Change_PSW_PM_to_UserMode: )
  202. R_ASM( mvfc psw, r1 ; get the current PSW value )
  203. R_ASM( btst #20, r1 ; check PSW.PM )
  204. R_ASM( bne.b R_LAB_NEXT(0);_psw_pm_is_user_mode )
  205. R_ASM(;_psw_pm_is_supervisor_mode: )
  206. R_ASM( pop r2 ; pop the return address value of caller )
  207. R_ASM( bset #20, r1 ; change PM = 0(Supervisor Mode) --> 1(User Mode) )
  208. R_ASM( push.l r1 ; push new PSW value which will be changed )
  209. R_ASM( push.l r2 ; push return address value )
  210. R_ASM( rte )
  211. R_LAB(0:;_psw_pm_is_user_mode: )
  212. R_ASM( ;rts )
  213. R_ASM_END
  214. }