drv_rtp.c 5.8 KB

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