1 /*
2  * Copyright 2018-2019 NXP
3  * All rights reserved.
4  *
5  * SPDX-License-Identifier: BSD-3-Clause
6  */
7 
8 #include "fsl_common.h"
9 #include "fsl_debug_console.h"
10 #include "board.h"
11 #if defined(SDK_I2C_BASED_COMPONENT_USED) && SDK_I2C_BASED_COMPONENT_USED
12 #include "fsl_lpi2c.h"
13 #endif /* SDK_I2C_BASED_COMPONENT_USED */
14 #include "fsl_iomuxc.h"
15 
16 /*******************************************************************************
17  * Variables
18  ******************************************************************************/
19 
20 /*******************************************************************************
21  * Code
22  ******************************************************************************/
23 
24 /* Get debug console frequency. */
BOARD_DebugConsoleSrcFreq(void)25 uint32_t BOARD_DebugConsoleSrcFreq(void)
26 {
27     uint32_t freq;
28 
29     /* To make it simple, we assume default PLL and divider settings, and the only variable
30        from application is use PLL3 source or OSC source */
31     if (CLOCK_GetMux(kCLOCK_UartMux) == 0) /* PLL3 div6 80M */
32     {
33         freq = (CLOCK_GetPllFreq(kCLOCK_PllUsb1) / 6U) / (CLOCK_GetDiv(kCLOCK_UartDiv) + 1U);
34     }
35     else
36     {
37         freq = CLOCK_GetOscFreq() / (CLOCK_GetDiv(kCLOCK_UartDiv) + 1U);
38     }
39 
40     return freq;
41 }
42 
43 /* Initialize debug console. */
BOARD_InitDebugConsole(void)44 void BOARD_InitDebugConsole(void)
45 {
46     uint32_t uartClkSrcFreq = BOARD_DebugConsoleSrcFreq();
47 
48     DbgConsole_Init(BOARD_DEBUG_UART_INSTANCE, BOARD_DEBUG_UART_BAUDRATE, BOARD_DEBUG_UART_TYPE, uartClkSrcFreq);
49 }
50 
51 /* MPU configuration. */
BOARD_ConfigMPU(void)52 void BOARD_ConfigMPU(void)
53 {
54 #if defined(__CC_ARM) || defined(__ARMCC_VERSION)
55     extern uint32_t Image$$RW_m_ncache$$Base[];
56     /* RW_m_ncache_unused is a auxiliary region which is used to get the whole size of noncache section */
57     extern uint32_t Image$$RW_m_ncache_unused$$Base[];
58     extern uint32_t Image$$RW_m_ncache_unused$$ZI$$Limit[];
59     uint32_t nonCacheStart = (uint32_t)Image$$RW_m_ncache$$Base;
60     uint32_t size          = ((uint32_t)Image$$RW_m_ncache_unused$$Base == nonCacheStart) ?
61                         0 :
62                         ((uint32_t)Image$$RW_m_ncache_unused$$ZI$$Limit - nonCacheStart);
63 #elif defined(__MCUXPRESSO)
64     extern uint32_t __base_NCACHE_REGION;
65     extern uint32_t __top_NCACHE_REGION;
66     uint32_t nonCacheStart = (uint32_t)(&__base_NCACHE_REGION);
67     uint32_t size          = (uint32_t)(&__top_NCACHE_REGION) - nonCacheStart;
68 #elif defined(__ICCARM__) || defined(__GNUC__)
69     extern uint32_t __NCACHE_REGION_START[];
70     extern uint32_t __NCACHE_REGION_SIZE[];
71     uint32_t nonCacheStart = (uint32_t)__NCACHE_REGION_START;
72     uint32_t size          = (uint32_t)__NCACHE_REGION_SIZE;
73 #endif
74     volatile uint32_t i = 0;
75 
76     /* Disable I cache and D cache */
77     if (SCB_CCR_IC_Msk == (SCB_CCR_IC_Msk & SCB->CCR))
78     {
79         SCB_DisableICache();
80     }
81     if (SCB_CCR_DC_Msk == (SCB_CCR_DC_Msk & SCB->CCR))
82     {
83         SCB_DisableDCache();
84     }
85 
86     /* Disable MPU */
87     ARM_MPU_Disable();
88 
89     /* MPU configure:
90      * Use ARM_MPU_RASR(DisableExec, AccessPermission, TypeExtField, IsShareable, IsCacheable, IsBufferable,
91      * SubRegionDisable, Size)
92      * API in mpu_armv7.h.
93      * param DisableExec       Instruction access (XN) disable bit,0=instruction fetches enabled, 1=instruction fetches
94      * disabled.
95      * param AccessPermission  Data access permissions, allows you to configure read/write access for User and
96      * Privileged mode.
97      *      Use MACROS defined in mpu_armv7.h:
98      * ARM_MPU_AP_NONE/ARM_MPU_AP_PRIV/ARM_MPU_AP_URO/ARM_MPU_AP_FULL/ARM_MPU_AP_PRO/ARM_MPU_AP_RO
99      * Combine TypeExtField/IsShareable/IsCacheable/IsBufferable to configure MPU memory access attributes.
100      *  TypeExtField  IsShareable  IsCacheable  IsBufferable   Memory Attribute    Shareability        Cache
101      *     0             x           0           0             Strongly Ordered    shareable
102      *     0             x           0           1              Device             shareable
103      *     0             0           1           0              Normal             not shareable   Outer and inner write
104      * through no write allocate
105      *     0             0           1           1              Normal             not shareable   Outer and inner write
106      * back no write allocate
107      *     0             1           1           0              Normal             shareable       Outer and inner write
108      * through no write allocate
109      *     0             1           1           1              Normal             shareable       Outer and inner write
110      * back no write allocate
111      *     1             0           0           0              Normal             not shareable   outer and inner
112      * noncache
113      *     1             1           0           0              Normal             shareable       outer and inner
114      * noncache
115      *     1             0           1           1              Normal             not shareable   outer and inner write
116      * back write/read acllocate
117      *     1             1           1           1              Normal             shareable       outer and inner write
118      * back write/read acllocate
119      *     2             x           0           0              Device              not shareable
120      *  Above are normal use settings, if your want to see more details or want to config different inner/outter cache
121      * policy.
122      *  please refer to Table 4-55 /4-56 in arm cortex-M7 generic user guide <dui0646b_cortex_m7_dgug.pdf>
123      * param SubRegionDisable  Sub-region disable field. 0=sub-region is enabled, 1=sub-region is disabled.
124      * param Size              Region size of the region to be configured. use ARM_MPU_REGION_SIZE_xxx MACRO in
125      * mpu_armv7.h.
126      */
127 
128     /*
129      * Add default region to deny access to whole address space to workaround speculative prefetch.
130      * Refer to Arm errata 1013783-B for more details.
131      *
132      */
133     /* Region 0 setting: Instruction access disabled, No data access permission. */
134     MPU->RBAR = ARM_MPU_RBAR(0, 0x00000000U);
135     MPU->RASR = ARM_MPU_RASR(1, ARM_MPU_AP_NONE, 0, 0, 0, 0, 0, ARM_MPU_REGION_SIZE_4GB);
136 
137     /* Region 1 setting: Memory with Device type, not shareable, non-cacheable. */
138     MPU->RBAR = ARM_MPU_RBAR(1, 0x80000000U);
139     MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 2, 0, 0, 0, 0, ARM_MPU_REGION_SIZE_512MB);
140 
141     /* Region 2 setting: Memory with Device type, not shareable,  non-cacheable. */
142     MPU->RBAR = ARM_MPU_RBAR(2, 0x60000000U);
143     MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 2, 0, 0, 0, 0, ARM_MPU_REGION_SIZE_512MB);
144 
145 #if defined(XIP_EXTERNAL_FLASH) && (XIP_EXTERNAL_FLASH == 1)
146     /* Region 3 setting: Memory with Normal type, not shareable, outer/inner write back. */
147     MPU->RBAR = ARM_MPU_RBAR(3, 0x60000000U);
148     MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_RO, 0, 0, 1, 1, 0, ARM_MPU_REGION_SIZE_8MB);
149 #endif
150 
151     /* Region 4 setting: Memory with Device type, not shareable, non-cacheable. */
152     MPU->RBAR = ARM_MPU_RBAR(4, 0x00000000U);
153     MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 2, 0, 0, 0, 0, ARM_MPU_REGION_SIZE_1GB);
154 
155     /* Region 5 setting: Memory with Normal type, not shareable, outer/inner write back */
156     MPU->RBAR = ARM_MPU_RBAR(5, 0x00000000U);
157     MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 0, 0, 1, 1, 0, ARM_MPU_REGION_SIZE_64KB);
158 
159     /* Region 6 setting: Memory with Normal type, not shareable, outer/inner write back */
160     MPU->RBAR = ARM_MPU_RBAR(6, 0x20000000U);
161     MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 0, 0, 1, 1, 0, ARM_MPU_REGION_SIZE_64KB);
162 
163     /* Region 7 setting: Memory with Normal type, not shareable, outer/inner write back */
164     MPU->RBAR = ARM_MPU_RBAR(7, 0x20200000U);
165     MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 0, 0, 1, 1, 0, ARM_MPU_REGION_SIZE_128KB);
166 
167     /* Region 8 setting: Memory with Normal type, not shareable, outer/inner write back */
168     MPU->RBAR = ARM_MPU_RBAR(8, 0x80000000U);
169     MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 0, 0, 1, 1, 0, ARM_MPU_REGION_SIZE_32MB);
170 
171     while ((size >> i) > 0x1U)
172     {
173         i++;
174     }
175 
176     if (i != 0)
177     {
178         /* The MPU region size should be 2^N, 5<=N<=32, region base should be multiples of size. */
179         assert(!(nonCacheStart % size));
180         assert(size == (uint32_t)(1 << i));
181         assert(i >= 5);
182 
183         /* Region 9 setting: Memory with Normal type, not shareable, non-cacheable */
184         MPU->RBAR = ARM_MPU_RBAR(9, nonCacheStart);
185         MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 1, 0, 0, 0, 0, i - 1);
186     }
187 
188     /* Region 10 setting: Memory with Device type, not shareable, non-cacheable */
189     MPU->RBAR = ARM_MPU_RBAR(10, 0x40000000);
190     MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 2, 0, 0, 0, 0, ARM_MPU_REGION_SIZE_4MB);
191 
192     /* Enable MPU */
193     ARM_MPU_Enable(MPU_CTRL_PRIVDEFENA_Msk | MPU_CTRL_HFNMIENA_Msk);
194 
195     /* Enable I cache and D cache */
196     SCB_EnableDCache();
197     SCB_EnableICache();
198 }
199 
200 #if defined(SDK_I2C_BASED_COMPONENT_USED) && SDK_I2C_BASED_COMPONENT_USED
BOARD_LPI2C_Init(LPI2C_Type * base,uint32_t clkSrc_Hz)201 void BOARD_LPI2C_Init(LPI2C_Type *base, uint32_t clkSrc_Hz)
202 {
203     lpi2c_master_config_t lpi2cConfig = {0};
204 
205     /*
206      * lpi2cConfig.debugEnable = false;
207      * lpi2cConfig.ignoreAck = false;
208      * lpi2cConfig.pinConfig = kLPI2C_2PinOpenDrain;
209      * lpi2cConfig.baudRate_Hz = 100000U;
210      * lpi2cConfig.busIdleTimeout_ns = 0;
211      * lpi2cConfig.pinLowTimeout_ns = 0;
212      * lpi2cConfig.sdaGlitchFilterWidth_ns = 0;
213      * lpi2cConfig.sclGlitchFilterWidth_ns = 0;
214      */
215     LPI2C_MasterGetDefaultConfig(&lpi2cConfig);
216     LPI2C_MasterInit(base, &lpi2cConfig, clkSrc_Hz);
217 }
218 
BOARD_LPI2C_Send(LPI2C_Type * base,uint8_t deviceAddress,uint32_t subAddress,uint8_t subAddressSize,uint8_t * txBuff,uint8_t txBuffSize)219 status_t BOARD_LPI2C_Send(LPI2C_Type *base,
220                           uint8_t deviceAddress,
221                           uint32_t subAddress,
222                           uint8_t subAddressSize,
223                           uint8_t *txBuff,
224                           uint8_t txBuffSize)
225 {
226     lpi2c_master_transfer_t xfer;
227 
228     xfer.flags          = kLPI2C_TransferDefaultFlag;
229     xfer.slaveAddress   = deviceAddress;
230     xfer.direction      = kLPI2C_Write;
231     xfer.subaddress     = subAddress;
232     xfer.subaddressSize = subAddressSize;
233     xfer.data           = txBuff;
234     xfer.dataSize       = txBuffSize;
235 
236     return LPI2C_MasterTransferBlocking(base, &xfer);
237 }
238 
BOARD_LPI2C_Receive(LPI2C_Type * base,uint8_t deviceAddress,uint32_t subAddress,uint8_t subAddressSize,uint8_t * rxBuff,uint8_t rxBuffSize)239 status_t BOARD_LPI2C_Receive(LPI2C_Type *base,
240                              uint8_t deviceAddress,
241                              uint32_t subAddress,
242                              uint8_t subAddressSize,
243                              uint8_t *rxBuff,
244                              uint8_t rxBuffSize)
245 {
246     lpi2c_master_transfer_t xfer;
247 
248     xfer.flags          = kLPI2C_TransferDefaultFlag;
249     xfer.slaveAddress   = deviceAddress;
250     xfer.direction      = kLPI2C_Read;
251     xfer.subaddress     = subAddress;
252     xfer.subaddressSize = subAddressSize;
253     xfer.data           = rxBuff;
254     xfer.dataSize       = rxBuffSize;
255 
256     return LPI2C_MasterTransferBlocking(base, &xfer);
257 }
258 
BOARD_Accel_I2C_Init(void)259 void BOARD_Accel_I2C_Init(void)
260 {
261     BOARD_LPI2C_Init(BOARD_ACCEL_I2C_BASEADDR, BOARD_ACCEL_I2C_CLOCK_FREQ);
262 }
263 
BOARD_Accel_I2C_Send(uint8_t deviceAddress,uint32_t subAddress,uint8_t subaddressSize,uint32_t txBuff)264 status_t BOARD_Accel_I2C_Send(uint8_t deviceAddress, uint32_t subAddress, uint8_t subaddressSize, uint32_t txBuff)
265 {
266     uint8_t data = (uint8_t)txBuff;
267 
268     return BOARD_LPI2C_Send(BOARD_ACCEL_I2C_BASEADDR, deviceAddress, subAddress, subaddressSize, &data, 1);
269 }
270 
BOARD_Accel_I2C_Receive(uint8_t deviceAddress,uint32_t subAddress,uint8_t subaddressSize,uint8_t * rxBuff,uint8_t rxBuffSize)271 status_t BOARD_Accel_I2C_Receive(
272     uint8_t deviceAddress, uint32_t subAddress, uint8_t subaddressSize, uint8_t *rxBuff, uint8_t rxBuffSize)
273 {
274     return BOARD_LPI2C_Receive(BOARD_ACCEL_I2C_BASEADDR, deviceAddress, subAddress, subaddressSize, rxBuff, rxBuffSize);
275 }
276 
BOARD_Codec_I2C_Init(void)277 void BOARD_Codec_I2C_Init(void)
278 {
279     BOARD_LPI2C_Init(BOARD_CODEC_I2C_BASEADDR, BOARD_CODEC_I2C_CLOCK_FREQ);
280 }
281 
BOARD_Codec_I2C_Send(uint8_t deviceAddress,uint32_t subAddress,uint8_t subAddressSize,const uint8_t * txBuff,uint8_t txBuffSize)282 status_t BOARD_Codec_I2C_Send(
283     uint8_t deviceAddress, uint32_t subAddress, uint8_t subAddressSize, const uint8_t *txBuff, uint8_t txBuffSize)
284 {
285     return BOARD_LPI2C_Send(BOARD_CODEC_I2C_BASEADDR, deviceAddress, subAddress, subAddressSize, (uint8_t *)txBuff,
286                             txBuffSize);
287 }
288 
BOARD_Codec_I2C_Receive(uint8_t deviceAddress,uint32_t subAddress,uint8_t subAddressSize,uint8_t * rxBuff,uint8_t rxBuffSize)289 status_t BOARD_Codec_I2C_Receive(
290     uint8_t deviceAddress, uint32_t subAddress, uint8_t subAddressSize, uint8_t *rxBuff, uint8_t rxBuffSize)
291 {
292     return BOARD_LPI2C_Receive(BOARD_CODEC_I2C_BASEADDR, deviceAddress, subAddress, subAddressSize, rxBuff, rxBuffSize);
293 }
294 #endif /* SDK_I2C_BASED_COMPONENT_USED */
295