1 /*
2  * Copyright (c) 2006-2023, RT-Thread Development Team
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Change Logs:
7  * Date           Author       Notes
8  * 2022-09-14     xjy198903    the first version for 1170
9  */
10 
11 #include <rtthread.h>
12 #ifdef BSP_USING_FLEXSPI
13 #include "board.h"
14 #include <rtdevice.h>
15 
16 #ifdef RT_USING_FINSH
17 #include <finsh.h>
18 #endif
19 
20 #include "flexspi_port.h"
21 #include "fsl_flexspi.h"
22 
23 #define COMBINATION_MODE 1U
24 #define FREE_RUNNING_MODE 1U
25 
26 #define FLEXSPI_DEBUG
27 #define LOG_TAG             "drv.flexspi"
28 #include <drv_log.h>
29 
30 static flexspi_device_config_t deviceconfig = {
31     .flexspiRootClk       = 12000000,
32     .flashSize            = FLASH_SIZE,
33     .CSIntervalUnit       = kFLEXSPI_CsIntervalUnit1SckCycle,
34     .CSInterval           = 2,
35     .CSHoldTime           = 3,
36     .CSSetupTime          = 3,
37     .dataValidTime        = 0,
38     .columnspace          = 0,
39     .enableWordAddress    = 0,
40     .AWRSeqIndex          = AWR_SEQ_INDEX,
41     .AWRSeqNumber         = AWR_SEQ_NUMBER,
42     .ARDSeqIndex          = ARD_SEQ_INDEX,
43     .ARDSeqNumber         = ARD_SEQ_NUMBER,
44     .AHBWriteWaitUnit     = kFLEXSPI_AhbWriteWaitUnit2AhbCycle,
45     .AHBWriteWaitInterval = 0,
46 };
47 
48 const uint32_t customLUT[CUSTOM_LUT_LENGTH] = {
49     /* 8bit mode */
50     [4 * ARD_SEQ_INDEX] =
51         FLEXSPI_LUT_SEQ(kFLEXSPI_Command_READ_DDR, kFLEXSPI_8PAD, 0x04, kFLEXSPI_Command_STOP, kFLEXSPI_8PAD, 0),
52 };
53 
flexspi_clock_init(clock_root_t root,uint8_t src,uint8_t div)54 static void flexspi_clock_init(clock_root_t root, uint8_t src, uint8_t div)
55 {
56     /*Clock setting for flexspi1*/
57     CLOCK_SetRootClockDiv(root, div);
58     CLOCK_SetRootClockMux(root, src);
59 }
60 
rt_hw_imxrt_flexspi_init(void)61 static int rt_hw_imxrt_flexspi_init(void)
62 {
63     flexspi_config_t config;
64     FLEXSPI_Type *base;
65 
66 #ifdef BSP_USING_FLEXSPI1
67     base = FLEXSPI1_CONTROL_BASE;
68 #else
69     base = FLEXSPI2_CONTROL_BASE;
70 #endif
71 
72     //Set root clk 80MHz
73     flexspi_clock_init(kCLOCK_Root_Flexspi1, CLOCK_SRC, CLOCK_DIV);
74 
75     /*Get FLEXSPI default settings and configure the flexspi. */
76     FLEXSPI_GetDefaultConfig(&config);
77 
78     /*Set AHB buffer size for reading data through AHB bus. */
79     config.ahbConfig.enableAHBPrefetch = true;
80     config.ahbConfig.enableAHBBufferable = true;
81     config.ahbConfig.enableReadAddressOpt = true;
82     config.ahbConfig.enableAHBCachable = true;
83     config.ahbConfig.enableClearAHBBufferOpt    = true;
84     config.rxSampleClock = FLEXSPI_RX_SAMPLE_CLOCK;
85     if(COMBINATION_MODE)
86     {
87         config.enableCombination = true;
88     }
89     if(FREE_RUNNING_MODE)
90     {
91         config.enableSckFreeRunning = true;
92     }
93     FLEXSPI_Init(base, &config);
94 
95     /* Configure flash settings according to serial flash feature. */
96     FLEXSPI_SetFlashConfig(base, &deviceconfig, FLASH_PORT);
97 
98     /* Update LUT table. */
99     FLEXSPI_UpdateLUT(base, 0, customLUT, CUSTOM_LUT_LENGTH);
100 
101     /* Do software reset. */
102     FLEXSPI_SoftwareReset(base);
103 
104     return 0;
105 }
106 INIT_DEVICE_EXPORT(rt_hw_imxrt_flexspi_init);
107 
108 #ifdef FLEXSPI_DEBUG
109 #ifdef FINSH_USING_MSH
110 
111 #define FLEXSPI_DATALEN 4U
112 static rt_uint32_t send_buf[FLEXSPI_DATALEN] = {0x11223344, 0x55667788, 0x12345678, 0x9900aabb};
113 static uint32_t recv_buf[FLEXSPI_DATALEN];
114 
115 /* read write 32bit test */
flexspi_test(void)116 static void flexspi_test(void)
117 {
118     volatile rt_uint32_t *flexspi = (rt_uint32_t *)FLEXSPI1_AHB_DATA_ADDRESS; /* FLEXSPI1 start address. */
119 
120     LOG_D("FLEXSPI Memory 32 bit Write Start\n");
121     *(flexspi + 15) = send_buf[3];
122     *(flexspi + 8) = send_buf[1];
123     *(flexspi + 11) = send_buf[2];
124     *(flexspi + 3) = send_buf[0];
125     LOG_D("FLEXSPI Memory 32 bit Write End\n");
126 
127     rt_memset(recv_buf, 0, sizeof(recv_buf));
128 
129     LOG_D("FLEXSPI Memory 32 bit Read Start\n");
130     recv_buf[2] = *(flexspi + 11);
131     recv_buf[3] = *(flexspi + 15);
132     recv_buf[1] = *(flexspi + 8);
133     recv_buf[0] = *(flexspi + 3);
134     LOG_D("FLEXSPI Memory 32 bit Read End\n");
135 
136     LOG_D("addr12 is 0x%x\n", recv_buf[0]);
137     LOG_D("addr32 is 0x%x\n", recv_buf[1]);
138     LOG_D("addr44 is 0x%x\n", recv_buf[2]);
139     LOG_D("addr60 is 0x%x\n", recv_buf[3]);
140 }
141 MSH_CMD_EXPORT(flexspi_test, flexspi test)
142 
143 #endif /* FLEXSPI_DEBUG */
144 #endif /* FINSH_USING_MSH */
145 #endif /* BSP_USING_FLEXSPI */
146