1 /*
2  * Copyright (c) 2006-2024, RT-Thread Development Team
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Change Logs:
7  * Date           Author       Notes
8  * 2024-10-28     yuanjie      first version
9  */
10 
11 #include <rtthread.h>
12 #include "hal_data.h"
13 #ifdef BSP_USING_HYPERRAM
14 
15 
16 #define DRV_DEBUG
17 #define LOG_TAG             "drv.hyper"
18 #include <drv_log.h>
19 
20 #define PSRAM_BANK_ADDR                 ((uint32_t)0x44000000UL)    // XSPI0 CS1
21 #define PSRAM_SIZE                      ((uint32_t)0x2000000UL)     // 32MBytes
22 #define PSRAM_DATA_WIDTH                16
23 
24 #ifdef RT_USING_MEMHEAP_AS_HEAP
25 static struct rt_memheap system_heap;
26 #endif
27 
28 
HYPERRAM_Init(void)29 static int HYPERRAM_Init(void)
30 {
31     int result = RT_EOK;
32     /* XSPI initial settings */
33     /* Initialize the PSRAM controller */
34     if (R_XSPI_HYPER_Open(&g_hyperbus0_ctrl, &g_hyperbus0_cfg) != FSP_SUCCESS)
35     {
36         LOG_E("HYPER RAM init failed!");
37         result = -RT_ERROR;
38     }
39     else
40     {
41         LOG_D("psram init success, mapped at 0x%X, size is %d bytes, data width is %d", PSRAM_BANK_ADDR, PSRAM_SIZE, PSRAM_DATA_WIDTH);
42 #ifdef RT_USING_MEMHEAP_AS_HEAP
43         /* If RT_USING_MEMHEAP_AS_HEAP is enabled, PSRAM is initialized to the heap */
44         rt_memheap_init(&system_heap, "psram", (void *)PSRAM_BANK_ADDR, PSRAM_SIZE);
45 #endif
46     }
47 
48     return result;
49 }
50 INIT_BOARD_EXPORT(HYPERRAM_Init);
51 
52 #ifdef DRV_DEBUG
53 #ifdef FINSH_USING_MSH
psram_test(void)54 int psram_test(void)
55 {
56     int i = 0;
57     uint32_t start_time = 0, time_cast = 0;
58 #if PSRAM_DATA_WIDTH == 8
59     char data_width = 1;
60     uint8_t data = 0;
61 #elif PSRAM_DATA_WIDTH == 16
62     char data_width = 2;
63     uint16_t data = 0;
64 #else
65     char data_width = 4;
66     uint32_t data = 0;
67 #endif
68 
69     /* write data */
70     LOG_D("Writing the %ld bytes data, waiting....", PSRAM_SIZE);
71     start_time = rt_tick_get();
72     for (i = 0; i < PSRAM_SIZE / data_width; i++)
73     {
74 #if PSRAM_DATA_WIDTH == 8
75         *(__IO uint8_t *)(PSRAM_BANK_ADDR + i * data_width) = (uint8_t)0x55;
76 #elif PSRAM_DATA_WIDTH == 16
77         *(__IO uint16_t *)(PSRAM_BANK_ADDR + i * data_width) = (uint16_t)0x5555;
78 #else
79         *(__IO uint32_t *)(PSRAM_BANK_ADDR + i * data_width) = (uint32_t)0x55555555;
80 #endif
81     }
82     time_cast = rt_tick_get() - start_time;
83     LOG_D("Write data success, total time: %d.%03dS.", time_cast / RT_TICK_PER_SECOND,
84           time_cast % RT_TICK_PER_SECOND / ((RT_TICK_PER_SECOND * 1 + 999) / 1000));
85 
86     /* read data */
87     LOG_D("start Reading and verifying data, waiting....");
88     for (i = 0; i < PSRAM_SIZE / data_width; i++)
89     {
90 #if PSRAM_DATA_WIDTH == 8
91         data = *(__IO uint8_t *)(PSRAM_BANK_ADDR + i * data_width);
92         if (data != 0x55)
93         {
94             LOG_E("PSRAM test failed!");
95             break;
96         }
97 #elif PSRAM_DATA_WIDTH == 16
98         data = *(__IO uint16_t *)(PSRAM_BANK_ADDR + i * data_width);
99         if (data != 0x5555)
100         {
101             LOG_E("PSRAM test failed!");
102             break;
103         }
104 #else
105         data = *(__IO uint32_t *)(PSRAM_BANK_ADDR + i * data_width);
106         if (data != 0x55555555)
107         {
108             LOG_E("PSRAM test failed!");
109             break;
110         }
111 #endif
112     }
113 
114     if (i >= PSRAM_SIZE / data_width)
115     {
116         LOG_D("PSRAM test success!");
117     }
118 
119     return RT_EOK;
120 }
121 MSH_CMD_EXPORT(psram_test, XSPI XIP hyper ram test)
122 #endif /* FINSH_USING_MSH */
123 #endif /* DRV_DEBUG */
124 #endif /* BSP_USING_HYPERRAM */
125