1 /*
2  * Copyright (c) 2006-2021, RT-Thread Development Team
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Change Logs:
7  * Date           Author       Notes
8  * 2020-02-23     Malongwei    first version
9  */
10 
11 #include <rtthread.h>
12 #include <rtdevice.h>
13 #include <board.h>
14 
15 #ifdef BSP_USING_SRAM
16 #include "drv_sram.h"
17 
18 #define DRV_DEBUG
19 #define LOG_TAG             "drv.sram"
20 #include <drv_log.h>
21 
22 #ifdef RT_USING_MEMHEAP_AS_HEAP
23 static struct rt_memheap system_heap;
24 #endif
25 
26 static SRAM_HandleTypeDef hsram;
27 
rt_hw_sram_init(void)28 static int rt_hw_sram_init(void)
29 {
30     int result = RT_EOK;
31 
32     FSMC_NORSRAM_TimingTypeDef Timing = {0};
33 
34     /** Perform the SRAM2 memory initialization sequence
35     */
36     hsram.Instance = FSMC_NORSRAM_DEVICE;
37     hsram.Extended = FSMC_NORSRAM_EXTENDED_DEVICE;
38     /* hsram.Init */
39     hsram.Init.NSBank = FSMC_NORSRAM_BANK3;
40     hsram.Init.DataAddressMux = FSMC_DATA_ADDRESS_MUX_DISABLE;
41     hsram.Init.MemoryType = FSMC_MEMORY_TYPE_SRAM;
42 #if SRAM_DATA_WIDTH == 8
43     hsram.Init.MemoryDataWidth = FSMC_NORSRAM_MEM_BUS_WIDTH_8;
44 #elif SRAM_DATA_WIDTH == 16
45     hsram.Init.MemoryDataWidth = FSMC_NORSRAM_MEM_BUS_WIDTH_16;
46 #else
47     hsram.Init.MemoryDataWidth = FSMC_NORSRAM_MEM_BUS_WIDTH_32;
48 #endif
49     hsram.Init.BurstAccessMode = FSMC_BURST_ACCESS_MODE_DISABLE;
50     hsram.Init.WaitSignalPolarity = FSMC_WAIT_SIGNAL_POLARITY_LOW;
51     hsram.Init.WrapMode = FSMC_WRAP_MODE_DISABLE;
52     hsram.Init.WaitSignalActive = FSMC_WAIT_TIMING_BEFORE_WS;
53     hsram.Init.WriteOperation = FSMC_WRITE_OPERATION_ENABLE;
54     hsram.Init.WaitSignal = FSMC_WAIT_SIGNAL_DISABLE;
55     hsram.Init.ExtendedMode = FSMC_EXTENDED_MODE_DISABLE;
56     hsram.Init.AsynchronousWait = FSMC_ASYNCHRONOUS_WAIT_DISABLE;
57     hsram.Init.WriteBurst = FSMC_WRITE_BURST_DISABLE;
58     hsram.Init.PageSize = FSMC_PAGE_SIZE_NONE;
59 
60 
61     /* Timing */
62     Timing.AddressSetupTime = 0;
63     Timing.AddressHoldTime = 0;
64     Timing.DataSetupTime = 8;
65     Timing.BusTurnAroundDuration = 0;
66     Timing.CLKDivision = 0;
67     Timing.DataLatency = 0;
68     Timing.AccessMode = FSMC_ACCESS_MODE_A;
69     /* ExtTiming */
70 
71     if (HAL_SRAM_Init(&hsram, &Timing, &Timing) != HAL_OK)
72     {
73         LOG_E("SRAM init failed!");
74         result = -RT_ERROR;
75     }
76     else
77     {
78         LOG_D("sram init success, mapped at 0x%X, size is %d bytes, data width is %d", SRAM_BANK_ADDR, SRAM_SIZE, SRAM_DATA_WIDTH);
79 #ifdef RT_USING_MEMHEAP_AS_HEAP
80         /* If RT_USING_MEMHEAP_AS_HEAP is enabled, SRAM is initialized to the heap */
81         rt_memheap_init(&system_heap, "sram", (void *)SRAM_BANK_ADDR, SRAM_SIZE);
82 #endif
83     }
84 
85     return result;
86 }
87 INIT_BOARD_EXPORT(rt_hw_sram_init);
88 
89 #ifdef DRV_DEBUG
90 #ifdef FINSH_USING_MSH
sram_test(void)91 static int sram_test(void)
92 {
93     int i = 0;
94     uint32_t start_time = 0, time_cast = 0;
95 #if SRAM_DATA_WIDTH == 8
96     char data_width = 1;
97     uint8_t data = 0;
98 #elif SRAM_DATA_WIDTH == 16
99     char data_width = 2;
100     uint16_t data = 0;
101 #else
102     char data_width = 4;
103     uint32_t data = 0;
104 #endif
105 
106     /* write data */
107     LOG_D("Writing the %ld bytes data, waiting....", SRAM_SIZE);
108     start_time = rt_tick_get();
109     for (i = 0; i < SRAM_SIZE / data_width; i++)
110     {
111 #if SRAM_DATA_WIDTH == 8
112         *(__IO uint8_t *)(SRAM_BANK_ADDR + i * data_width) = (uint8_t)0x55;
113 #elif SRAM_DATA_WIDTH == 16
114         *(__IO uint16_t *)(SRAM_BANK_ADDR + i * data_width) = (uint16_t)0x5555;
115 #else
116         *(__IO uint32_t *)(SRAM_BANK_ADDR + i * data_width) = (uint32_t)0x55555555;
117 #endif
118     }
119     time_cast = rt_tick_get() - start_time;
120     LOG_D("Write data success, total time: %d.%03dS.", time_cast / RT_TICK_PER_SECOND,
121           time_cast % RT_TICK_PER_SECOND / ((RT_TICK_PER_SECOND * 1 + 999) / 1000));
122 
123     /* read data */
124     LOG_D("start Reading and verifying data, waiting....");
125     for (i = 0; i < SRAM_SIZE / data_width; i++)
126     {
127 #if SRAM_DATA_WIDTH == 8
128         data = *(__IO uint8_t *)(SRAM_BANK_ADDR + i * data_width);
129         if (data != 0x55)
130         {
131             LOG_E("SRAM test failed!");
132             break;
133         }
134 #elif SRAM_DATA_WIDTH == 16
135         data = *(__IO uint16_t *)(SRAM_BANK_ADDR + i * data_width);
136         if (data != 0x5555)
137         {
138             LOG_E("SRAM test failed!");
139             break;
140         }
141 #else
142         data = *(__IO uint32_t *)(SRAM_BANK_ADDR + i * data_width);
143         if (data != 0x55555555)
144         {
145             LOG_E("SRAM test failed!");
146             break;
147         }
148 #endif
149     }
150 
151     if (i >= SRAM_SIZE / data_width)
152     {
153         LOG_D("SRAM test success!");
154     }
155 
156     return RT_EOK;
157 }
158 MSH_CMD_EXPORT(sram_test, sram test);
159 #endif /* FINSH_USING_MSH */
160 #endif /* DRV_DEBUG */
161 #endif /* BSP_USING_SRAM */
162