drv_rtp.c 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. /**************************************************************************//**
  2. * @copyright (C) 2020 Nuvoton Technology Corp. All rights reserved.
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2022-9-27 Wayne First version
  9. *
  10. ******************************************************************************/
  11. #include <rtconfig.h>
  12. #if defined(BSP_USING_RTP) && defined(RT_USING_DFS)
  13. #define LOG_TAG "drv.rtp"
  14. #define DBG_SECTION_NAME LOG_TAG
  15. #define DBG_LEVEL LOG_LVL_INFO
  16. #define DBG_COLOR
  17. #include <rtdbg.h>
  18. #include <rtdevice.h>
  19. #include "drv_sys.h"
  20. #include <dfs_file.h>
  21. #include <unistd.h>
  22. #include <stdio.h>
  23. #include <sys/stat.h>
  24. #include <sys/statfs.h>
  25. #include "drv_sspcc.h"
  26. /* Link to rtthread.bin in ma35-rtp folder. */
  27. #define PATH_RTP_INCBIN "..//ma35-rtp//rtthread.bin"
  28. #define READ_BLOCK_SIZE 128
  29. #if !defined(PATH_RTP_FW_FILE)
  30. #define PATH_RTP_FW_FILE "/mnt/sd1p0/rtp.bin"
  31. #endif
  32. #if defined(RTP_USING_AT_STARTUP)
  33. #define STR2(x) #x
  34. #define STR(x) STR2(x)
  35. #define INCBIN(name, file) \
  36. __asm__(".section .rodata\n" \
  37. ".global incbin_" STR(name) "_start\n" \
  38. ".balign 16\n" \
  39. "incbin_" STR(name) "_start:\n" \
  40. ".incbin \"" file "\"\n" \
  41. \
  42. ".global incbin_" STR(name) "_end\n" \
  43. ".balign 1\n" \
  44. "incbin_" STR(name) "_end:\n" \
  45. ".byte 0\n" \
  46. ); \
  47. extern const __attribute__((aligned(16))) void* incbin_ ## name ## _start; \
  48. extern const void* incbin_ ## name ## _end; \
  49. INCBIN(rtp, PATH_RTP_INCBIN);
  50. static int nu_rtp_load_from_memory(void *pvBuf, int len)
  51. {
  52. int remaining;
  53. if (!pvBuf || !len)
  54. goto exit_nu_rtp_load_from_memory;
  55. /* Limit memory usage to 4MB. */
  56. if (len > REGION_MAXSIZE_LIMIT)
  57. goto exit_nu_rtp_load_from_memory;
  58. remaining = len;
  59. /* Copy to SRAM0 */
  60. if (remaining > REGION_MAXSIZE_SRAM0)
  61. {
  62. rt_memcpy((void *)REGION_ADDR_SRAM0, pvBuf, REGION_MAXSIZE_SRAM0);
  63. remaining -= REGION_MAXSIZE_SRAM0;
  64. }
  65. else
  66. {
  67. rt_memcpy((void *)REGION_ADDR_SRAM0, pvBuf, remaining);
  68. remaining -= remaining;
  69. }
  70. /* Copy to non-cacheable DDR memory if the size over 128KB. */
  71. if (remaining > 0)
  72. {
  73. rt_memcpy((void *)REGION_ADDR_DDR, (pvBuf + REGION_MAXSIZE_SRAM0), remaining);
  74. remaining -= remaining;
  75. }
  76. return 0;
  77. exit_nu_rtp_load_from_memory:
  78. return -1;
  79. }
  80. #endif
  81. rt_weak void nu_rtp_sspcc_setup(void)
  82. {
  83. SSPCC_SET_REALM(SSPCC_UART16, SSPCC_SSET_SUBM);
  84. SSPCC_SET_GPIO_REALM(PK, 0, SSPCC_SSET_SUBM);
  85. SSPCC_SET_GPIO_REALM(PK, 1, SSPCC_SSET_SUBM);
  86. SSPCC_SET_GPIO_REALM(PK, 2, SSPCC_SSET_SUBM);
  87. SSPCC_SET_GPIO_REALM(PK, 3, SSPCC_SSET_SUBM);
  88. }
  89. static void nu_rtp_init(void)
  90. {
  91. /* Enable WDT1/WDT2 reset */
  92. SYS->MISCRFCR |= SYS_MISCRFCR_WDT1RSTAEN_Msk | SYS_MISCRFCR_WDT2RSTAEN_Msk | SYS_MISCRFCR_WDT1RSTMEN_Msk;
  93. /* Enable M4 I/D cache */
  94. SYS->MISCFCR0 |= (SYS_MISCFCR0_RTPICACHEN_Msk | SYS_MISCFCR0_RTPDCACHEN_Msk | SYS_MISCFCR0_RTPDRMAEN_Msk);
  95. nu_rtp_sspcc_setup();
  96. }
  97. void nu_rtp_start(void)
  98. {
  99. /* Enable RTP clock */
  100. CLK_EnableModuleClock(RTP_MODULE);
  101. /* Disable M4 Core reset*/
  102. SYS->IPRST0 &= ~SYS_IPRST0_CM4RST_Msk;
  103. }
  104. MSH_CMD_EXPORT(nu_rtp_start, start rtp);
  105. void nu_rtp_stop(void)
  106. {
  107. /* Enable M4 Core reset*/
  108. SYS->IPRST0 |= SYS_IPRST0_CM4RST_Msk;
  109. /* Disable RTP clock */
  110. CLK_DisableModuleClock(RTP_MODULE);
  111. }
  112. MSH_CMD_EXPORT(nu_rtp_stop, stop rtp);
  113. #if defined(RT_USING_DFS)
  114. static int nu_rtp_load_from_file(char *szAbsFilePath)
  115. {
  116. int fd, ret = -1;
  117. char *buff_ptr = RT_NULL;
  118. rt_size_t offset = 0;
  119. fd = open(szAbsFilePath, O_RDONLY);
  120. if (fd < 0)
  121. {
  122. LOG_E("Could not open %s for rtp loading.", szAbsFilePath);
  123. goto exit_nu_rtp_load_from_file;
  124. }
  125. while (1)
  126. {
  127. int length;
  128. if (offset < REGION_MAXSIZE_SRAM0)
  129. {
  130. buff_ptr = (char *)(REGION_ADDR_SRAM0 + offset);
  131. }
  132. else
  133. {
  134. buff_ptr = (char *)(REGION_ADDR_DDR + offset - REGION_MAXSIZE_SRAM0);
  135. }
  136. /* Limit memory usage to 4MB. */
  137. if ((offset + READ_BLOCK_SIZE) >= REGION_MAXSIZE_SRAM0)
  138. goto exit_nu_rtp_load_from_file;
  139. length = read(fd, buff_ptr, READ_BLOCK_SIZE);
  140. if (length <= 0) break;
  141. offset += length;
  142. //rt_kprintf("readed (%d/%d) to %08x\n", length, offset, buff_ptr);
  143. }
  144. ret = 0;
  145. exit_nu_rtp_load_from_file:
  146. if (fd >= 0)
  147. close(fd);
  148. return ret;
  149. }
  150. int nu_rtp_load_run(int argc, char *argv[])
  151. {
  152. char *szFilePath = RT_NULL;
  153. if (argc == 1)
  154. {
  155. szFilePath = PATH_RTP_FW_FILE;
  156. }
  157. else if (argc == 2)
  158. {
  159. szFilePath = argv[1];
  160. }
  161. nu_rtp_stop();
  162. nu_rtp_init();
  163. if (!szFilePath || nu_rtp_load_from_file(szFilePath) < 0)
  164. return -1;
  165. LOG_I("Loaded %s, then run...", szFilePath);
  166. nu_rtp_start();
  167. return 0;
  168. }
  169. MSH_CMD_EXPORT(nu_rtp_load_run, load rtp code then run);
  170. #endif
  171. int rt_hw_rtp_init(void)
  172. {
  173. #if defined(RTP_USING_AT_STARTUP)
  174. int fw_size = (int)((char *)&incbin_rtp_end - (char *)&incbin_rtp_start);
  175. LOG_I("INCBIN RTP Start = %p", &incbin_rtp_start);
  176. LOG_I("INCBIN RTP Size = %p", fw_size);
  177. #endif
  178. /* Enable RTP and reset M4 reset */
  179. nu_rtp_init();
  180. #if defined(RTP_USING_AT_STARTUP)
  181. nu_rtp_stop();
  182. nu_rtp_load_from_memory(&incbin_rtp_start, fw_size);
  183. #endif
  184. nu_rtp_start();
  185. return 0;
  186. }
  187. INIT_BOARD_EXPORT(rt_hw_rtp_init);
  188. #endif //#if defined(BSP_USING_RTP)