forked from xuos/xiuos
support OPCUA and LWIP
This commit is contained in:
@@ -5,32 +5,40 @@
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2021 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file board.c
|
||||
* @brief support imxrt1052-board init configure and start-up
|
||||
* @version 1.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2021-05-29
|
||||
*/
|
||||
|
||||
/*************************************************
|
||||
File name: board.c
|
||||
Description: support imxrt1052-board init configure and driver/task/... init
|
||||
Others: take SDK_2.6.1_MIMXRT1052xxxxB/devices/MIMXRT1052/project_template/board.c
|
||||
History:
|
||||
1. Date: 2021-05-29
|
||||
Author: AIIT XUOS Lab
|
||||
Modification:
|
||||
1. support imxrt1052-board InitBoardHardware
|
||||
*************************************************/
|
||||
* @file board.c
|
||||
* @brief relative configure for ok1052-c
|
||||
* @version 1.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2021.11.11
|
||||
*/
|
||||
|
||||
#include "fsl_common.h"
|
||||
#include "board.h"
|
||||
#include "pin_mux.h"
|
||||
|
||||
#if defined(SDK_I2C_BASED_COMPONENT_USED) && SDK_I2C_BASED_COMPONENT_USED
|
||||
#include "fsl_lpi2c.h"
|
||||
#endif /* SDK_I2C_BASED_COMPONENT_USED */
|
||||
#include "fsl_iomuxc.h"
|
||||
#include "fsl_gpio.h"
|
||||
#include <connect_uart.h>
|
||||
#include "fsl_lpuart.h"
|
||||
|
||||
#include <connect_ethernet.h>
|
||||
#include <connect_uart.h>
|
||||
|
||||
#define NVIC_PRIORITYGROUP_0 0x00000007U /*!< 0 bits for pre-emption priority
|
||||
4 bits for subpriority */
|
||||
#define NVIC_PRIORITYGROUP_1 0x00000006U /*!< 1 bits for pre-emption priority
|
||||
@@ -40,57 +48,478 @@ Modification:
|
||||
#define NVIC_PRIORITYGROUP_3 0x00000004U /*!< 3 bits for pre-emption priority
|
||||
1 bits for subpriority */
|
||||
#define NVIC_PRIORITYGROUP_4 0x00000003U /*!< 4 bits for pre-emption priority
|
||||
0 bits for subpriority */
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* Variables
|
||||
******************************************************************************/
|
||||
|
||||
/*******************************************************************************
|
||||
* Code
|
||||
******************************************************************************/
|
||||
|
||||
#if 0
|
||||
/* Get debug console frequency. */
|
||||
uint32_t BOARD_DebugConsoleSrcFreq(void)
|
||||
{
|
||||
uint32_t freq;
|
||||
|
||||
/* To make it simple, we assume default PLL and divider settings, and the only variable
|
||||
from application is use PLL3 source or OSC source */
|
||||
if (CLOCK_GetMux(kCLOCK_UartMux) == 0) /* PLL3 div6 80M */
|
||||
{
|
||||
freq = (CLOCK_GetPllFreq(kCLOCK_PllUsb1) / 6U) / (CLOCK_GetDiv(kCLOCK_UartDiv) + 1U);
|
||||
}
|
||||
else
|
||||
{
|
||||
freq = CLOCK_GetOscFreq() / (CLOCK_GetDiv(kCLOCK_UartDiv) + 1U);
|
||||
}
|
||||
|
||||
return freq;
|
||||
}
|
||||
|
||||
/* Initialize debug console. */
|
||||
void BOARD_InitDebugConsole(void)
|
||||
{
|
||||
uint32_t uartClkSrcFreq = BOARD_DebugConsoleSrcFreq();
|
||||
|
||||
DbgConsole_Init(BOARD_DEBUG_UART_INSTANCE, BOARD_DEBUG_UART_BAUDRATE, BOARD_DEBUG_UART_TYPE, uartClkSrcFreq);
|
||||
}
|
||||
|
||||
#if defined(SDK_I2C_BASED_COMPONENT_USED) && SDK_I2C_BASED_COMPONENT_USED
|
||||
void BOARD_LPI2C_Init(LPI2C_Type *base, uint32_t clkSrc_Hz)
|
||||
{
|
||||
lpi2c_master_config_t lpi2cConfig = {0};
|
||||
|
||||
/*
|
||||
* lpi2cConfig.debugEnable = false;
|
||||
* lpi2cConfig.ignoreAck = false;
|
||||
* lpi2cConfig.pinConfig = kLPI2C_2PinOpenDrain;
|
||||
* lpi2cConfig.baudRate_Hz = 100000U;
|
||||
* lpi2cConfig.busIdleTimeout_ns = 0;
|
||||
* lpi2cConfig.pinLowTimeout_ns = 0;
|
||||
* lpi2cConfig.sdaGlitchFilterWidth_ns = 0;
|
||||
* lpi2cConfig.sclGlitchFilterWidth_ns = 0;
|
||||
*/
|
||||
LPI2C_MasterGetDefaultConfig(&lpi2cConfig);
|
||||
LPI2C_MasterInit(base, &lpi2cConfig, clkSrc_Hz);
|
||||
}
|
||||
|
||||
status_t BOARD_LPI2C_Send(LPI2C_Type *base,
|
||||
uint8_t deviceAddress,
|
||||
uint32_t subAddress,
|
||||
uint8_t subAddressSize,
|
||||
uint8_t *txBuff,
|
||||
uint8_t txBuffSize)
|
||||
{
|
||||
status_t reVal;
|
||||
|
||||
/* Send master blocking data to slave */
|
||||
reVal = LPI2C_MasterStart(base, deviceAddress, kLPI2C_Write);
|
||||
if (kStatus_Success == reVal)
|
||||
{
|
||||
while (LPI2C_MasterGetStatusFlags(base) & kLPI2C_MasterNackDetectFlag)
|
||||
{
|
||||
}
|
||||
|
||||
reVal = LPI2C_MasterSend(base, &subAddress, subAddressSize);
|
||||
if (reVal != kStatus_Success)
|
||||
{
|
||||
return reVal;
|
||||
}
|
||||
|
||||
reVal = LPI2C_MasterSend(base, txBuff, txBuffSize);
|
||||
if (reVal != kStatus_Success)
|
||||
{
|
||||
return reVal;
|
||||
}
|
||||
|
||||
reVal = LPI2C_MasterStop(base);
|
||||
if (reVal != kStatus_Success)
|
||||
{
|
||||
return reVal;
|
||||
}
|
||||
}
|
||||
|
||||
return reVal;
|
||||
}
|
||||
|
||||
status_t BOARD_LPI2C_Receive(LPI2C_Type *base,
|
||||
uint8_t deviceAddress,
|
||||
uint32_t subAddress,
|
||||
uint8_t subAddressSize,
|
||||
uint8_t *rxBuff,
|
||||
uint8_t rxBuffSize)
|
||||
{
|
||||
status_t reVal;
|
||||
|
||||
reVal = LPI2C_MasterStart(base, deviceAddress, kLPI2C_Write);
|
||||
if (kStatus_Success == reVal)
|
||||
{
|
||||
while (LPI2C_MasterGetStatusFlags(base) & kLPI2C_MasterNackDetectFlag)
|
||||
{
|
||||
}
|
||||
|
||||
reVal = LPI2C_MasterSend(base, &subAddress, subAddressSize);
|
||||
if (reVal != kStatus_Success)
|
||||
{
|
||||
return reVal;
|
||||
}
|
||||
|
||||
reVal = LPI2C_MasterRepeatedStart(base, deviceAddress, kLPI2C_Read);
|
||||
|
||||
if (reVal != kStatus_Success)
|
||||
{
|
||||
return reVal;
|
||||
}
|
||||
|
||||
reVal = LPI2C_MasterReceive(base, rxBuff, rxBuffSize);
|
||||
if (reVal != kStatus_Success)
|
||||
{
|
||||
return reVal;
|
||||
}
|
||||
|
||||
reVal = LPI2C_MasterStop(base);
|
||||
if (reVal != kStatus_Success)
|
||||
{
|
||||
return reVal;
|
||||
}
|
||||
}
|
||||
return reVal;
|
||||
}
|
||||
|
||||
status_t BOARD_LPI2C_SendSCCB(LPI2C_Type *base,
|
||||
uint8_t deviceAddress,
|
||||
uint32_t subAddress,
|
||||
uint8_t subAddressSize,
|
||||
uint8_t *txBuff,
|
||||
uint8_t txBuffSize)
|
||||
{
|
||||
return BOARD_LPI2C_Send(base, deviceAddress, subAddress, subAddressSize, txBuff, txBuffSize);
|
||||
}
|
||||
|
||||
status_t BOARD_LPI2C_ReceiveSCCB(LPI2C_Type *base,
|
||||
uint8_t deviceAddress,
|
||||
uint32_t subAddress,
|
||||
uint8_t subAddressSize,
|
||||
uint8_t *rxBuff,
|
||||
uint8_t rxBuffSize)
|
||||
{
|
||||
status_t reVal;
|
||||
|
||||
reVal = LPI2C_MasterStart(base, deviceAddress, kLPI2C_Write);
|
||||
if (kStatus_Success == reVal)
|
||||
{
|
||||
while (LPI2C_MasterGetStatusFlags(base) & kLPI2C_MasterNackDetectFlag)
|
||||
{
|
||||
}
|
||||
|
||||
reVal = LPI2C_MasterSend(base, &subAddress, subAddressSize);
|
||||
if (reVal != kStatus_Success)
|
||||
{
|
||||
return reVal;
|
||||
}
|
||||
|
||||
/* SCCB does not support LPI2C repeat start, must stop then start. */
|
||||
reVal = LPI2C_MasterStop(base);
|
||||
|
||||
if (reVal != kStatus_Success)
|
||||
{
|
||||
return reVal;
|
||||
}
|
||||
|
||||
reVal = LPI2C_MasterStart(base, deviceAddress, kLPI2C_Read);
|
||||
|
||||
if (reVal != kStatus_Success)
|
||||
{
|
||||
return reVal;
|
||||
}
|
||||
|
||||
reVal = LPI2C_MasterReceive(base, rxBuff, rxBuffSize);
|
||||
if (reVal != kStatus_Success)
|
||||
{
|
||||
return reVal;
|
||||
}
|
||||
|
||||
reVal = LPI2C_MasterStop(base);
|
||||
if (reVal != kStatus_Success)
|
||||
{
|
||||
return reVal;
|
||||
}
|
||||
}
|
||||
return reVal;
|
||||
}
|
||||
|
||||
void BOARD_Accel_I2C_Init(void)
|
||||
{
|
||||
BOARD_LPI2C_Init(BOARD_ACCEL_I2C_BASEADDR, BOARD_ACCEL_I2C_CLOCK_FREQ);
|
||||
}
|
||||
|
||||
status_t BOARD_Accel_I2C_Send(uint8_t deviceAddress, uint32_t subAddress, uint8_t subaddressSize, uint32_t txBuff)
|
||||
{
|
||||
uint8_t data = (uint8_t)txBuff;
|
||||
|
||||
return BOARD_LPI2C_Send(BOARD_ACCEL_I2C_BASEADDR, deviceAddress, subAddress, subaddressSize, &data, 1);
|
||||
}
|
||||
|
||||
status_t BOARD_Accel_I2C_Receive(
|
||||
uint8_t deviceAddress, uint32_t subAddress, uint8_t subaddressSize, uint8_t *rxBuff, uint8_t rxBuffSize)
|
||||
{
|
||||
return BOARD_LPI2C_Receive(BOARD_ACCEL_I2C_BASEADDR, deviceAddress, subAddress, subaddressSize, rxBuff, rxBuffSize);
|
||||
}
|
||||
|
||||
void BOARD_Codec_I2C_Init(void)
|
||||
{
|
||||
BOARD_LPI2C_Init(BOARD_CODEC_I2C_BASEADDR, BOARD_CODEC_I2C_CLOCK_FREQ);
|
||||
}
|
||||
|
||||
status_t BOARD_Codec_I2C_Send(
|
||||
uint8_t deviceAddress, uint32_t subAddress, uint8_t subAddressSize, const uint8_t *txBuff, uint8_t txBuffSize)
|
||||
{
|
||||
return BOARD_LPI2C_Send(BOARD_CODEC_I2C_BASEADDR, deviceAddress, subAddress, subAddressSize, (uint8_t *)txBuff,
|
||||
txBuffSize);
|
||||
}
|
||||
|
||||
status_t BOARD_Codec_I2C_Receive(
|
||||
uint8_t deviceAddress, uint32_t subAddress, uint8_t subAddressSize, uint8_t *rxBuff, uint8_t rxBuffSize)
|
||||
{
|
||||
return BOARD_LPI2C_Receive(BOARD_CODEC_I2C_BASEADDR, deviceAddress, subAddress, subAddressSize, rxBuff, rxBuffSize);
|
||||
}
|
||||
|
||||
void BOARD_Camera_I2C_Init(void)
|
||||
{
|
||||
CLOCK_SetMux(kCLOCK_Lpi2cMux, BOARD_CAMERA_I2C_CLOCK_SOURCE_SELECT);
|
||||
CLOCK_SetDiv(kCLOCK_Lpi2cDiv, BOARD_CAMERA_I2C_CLOCK_SOURCE_DIVIDER);
|
||||
BOARD_LPI2C_Init(BOARD_CAMERA_I2C_BASEADDR, BOARD_CAMERA_I2C_CLOCK_FREQ);
|
||||
}
|
||||
|
||||
status_t BOARD_Camera_I2C_Send(
|
||||
uint8_t deviceAddress, uint32_t subAddress, uint8_t subAddressSize, const uint8_t *txBuff, uint8_t txBuffSize)
|
||||
{
|
||||
return BOARD_LPI2C_Send(BOARD_CAMERA_I2C_BASEADDR, deviceAddress, subAddress, subAddressSize, (uint8_t *)txBuff,
|
||||
txBuffSize);
|
||||
}
|
||||
|
||||
status_t BOARD_Camera_I2C_Receive(
|
||||
uint8_t deviceAddress, uint32_t subAddress, uint8_t subAddressSize, uint8_t *rxBuff, uint8_t rxBuffSize)
|
||||
{
|
||||
return BOARD_LPI2C_Receive(BOARD_CAMERA_I2C_BASEADDR, deviceAddress, subAddress, subAddressSize, rxBuff,
|
||||
rxBuffSize);
|
||||
}
|
||||
|
||||
status_t BOARD_Camera_I2C_SendSCCB(
|
||||
uint8_t deviceAddress, uint32_t subAddress, uint8_t subAddressSize, const uint8_t *txBuff, uint8_t txBuffSize)
|
||||
{
|
||||
return BOARD_LPI2C_SendSCCB(BOARD_CAMERA_I2C_BASEADDR, deviceAddress, subAddress, subAddressSize, (uint8_t *)txBuff,
|
||||
txBuffSize);
|
||||
}
|
||||
|
||||
status_t BOARD_Camera_I2C_ReceiveSCCB(
|
||||
uint8_t deviceAddress, uint32_t subAddress, uint8_t subAddressSize, uint8_t *rxBuff, uint8_t rxBuffSize)
|
||||
{
|
||||
return BOARD_LPI2C_ReceiveSCCB(BOARD_CAMERA_I2C_BASEADDR, deviceAddress, subAddress, subAddressSize, rxBuff,
|
||||
rxBuffSize);
|
||||
}
|
||||
#endif /* SDK_I2C_BASED_COMPONENT_USED */
|
||||
#endif
|
||||
|
||||
|
||||
void BOARD_SD_Pin_Config(uint32_t speed, uint32_t strength)
|
||||
{
|
||||
IOMUXC_SetPinConfig(IOMUXC_GPIO_SD_B0_00_USDHC1_CMD,
|
||||
IOMUXC_SW_PAD_CTL_PAD_SPEED(speed) | IOMUXC_SW_PAD_CTL_PAD_SRE_MASK |
|
||||
IOMUXC_SW_PAD_CTL_PAD_PKE_MASK | IOMUXC_SW_PAD_CTL_PAD_PUE_MASK |
|
||||
IOMUXC_SW_PAD_CTL_PAD_HYS_MASK | IOMUXC_SW_PAD_CTL_PAD_PUS(1) |
|
||||
IOMUXC_SW_PAD_CTL_PAD_DSE(strength));
|
||||
IOMUXC_SetPinConfig(IOMUXC_GPIO_SD_B0_01_USDHC1_CLK,
|
||||
IOMUXC_SW_PAD_CTL_PAD_SPEED(speed) | IOMUXC_SW_PAD_CTL_PAD_SRE_MASK |
|
||||
IOMUXC_SW_PAD_CTL_PAD_HYS_MASK | IOMUXC_SW_PAD_CTL_PAD_PUS(0) |
|
||||
IOMUXC_SW_PAD_CTL_PAD_DSE(strength));
|
||||
IOMUXC_SetPinConfig(IOMUXC_GPIO_SD_B0_02_USDHC1_DATA0,
|
||||
IOMUXC_SW_PAD_CTL_PAD_SPEED(speed) | IOMUXC_SW_PAD_CTL_PAD_SRE_MASK |
|
||||
IOMUXC_SW_PAD_CTL_PAD_PKE_MASK | IOMUXC_SW_PAD_CTL_PAD_PUE_MASK |
|
||||
IOMUXC_SW_PAD_CTL_PAD_HYS_MASK | IOMUXC_SW_PAD_CTL_PAD_PUS(1) |
|
||||
IOMUXC_SW_PAD_CTL_PAD_DSE(strength));
|
||||
IOMUXC_SetPinConfig(IOMUXC_GPIO_SD_B0_03_USDHC1_DATA1,
|
||||
IOMUXC_SW_PAD_CTL_PAD_SPEED(speed) | IOMUXC_SW_PAD_CTL_PAD_SRE_MASK |
|
||||
IOMUXC_SW_PAD_CTL_PAD_PKE_MASK | IOMUXC_SW_PAD_CTL_PAD_PUE_MASK |
|
||||
IOMUXC_SW_PAD_CTL_PAD_HYS_MASK | IOMUXC_SW_PAD_CTL_PAD_PUS(1) |
|
||||
IOMUXC_SW_PAD_CTL_PAD_DSE(strength));
|
||||
IOMUXC_SetPinConfig(IOMUXC_GPIO_SD_B0_04_USDHC1_DATA2,
|
||||
IOMUXC_SW_PAD_CTL_PAD_SPEED(speed) | IOMUXC_SW_PAD_CTL_PAD_SRE_MASK |
|
||||
IOMUXC_SW_PAD_CTL_PAD_PKE_MASK | IOMUXC_SW_PAD_CTL_PAD_PUE_MASK |
|
||||
IOMUXC_SW_PAD_CTL_PAD_HYS_MASK | IOMUXC_SW_PAD_CTL_PAD_PUS(1) |
|
||||
IOMUXC_SW_PAD_CTL_PAD_DSE(strength));
|
||||
IOMUXC_SetPinConfig(IOMUXC_GPIO_SD_B0_05_USDHC1_DATA3,
|
||||
IOMUXC_SW_PAD_CTL_PAD_SPEED(speed) | IOMUXC_SW_PAD_CTL_PAD_SRE_MASK |
|
||||
IOMUXC_SW_PAD_CTL_PAD_PKE_MASK | IOMUXC_SW_PAD_CTL_PAD_PUE_MASK |
|
||||
IOMUXC_SW_PAD_CTL_PAD_HYS_MASK | IOMUXC_SW_PAD_CTL_PAD_PUS(1) |
|
||||
IOMUXC_SW_PAD_CTL_PAD_DSE(strength));
|
||||
}
|
||||
|
||||
void BOARD_MMC_Pin_Config(uint32_t speed, uint32_t strength)
|
||||
{
|
||||
IOMUXC_SetPinConfig(IOMUXC_GPIO_SD_B1_05_USDHC2_CMD,
|
||||
IOMUXC_SW_PAD_CTL_PAD_SPEED(speed) | IOMUXC_SW_PAD_CTL_PAD_SRE_MASK |
|
||||
IOMUXC_SW_PAD_CTL_PAD_PKE_MASK | IOMUXC_SW_PAD_CTL_PAD_PUE_MASK |
|
||||
IOMUXC_SW_PAD_CTL_PAD_HYS_MASK | IOMUXC_SW_PAD_CTL_PAD_PUS(1) |
|
||||
IOMUXC_SW_PAD_CTL_PAD_DSE(strength));
|
||||
IOMUXC_SetPinConfig(IOMUXC_GPIO_SD_B1_04_USDHC2_CLK,
|
||||
IOMUXC_SW_PAD_CTL_PAD_SPEED(speed) | IOMUXC_SW_PAD_CTL_PAD_SRE_MASK |
|
||||
IOMUXC_SW_PAD_CTL_PAD_HYS_MASK | IOMUXC_SW_PAD_CTL_PAD_PUS(0) |
|
||||
IOMUXC_SW_PAD_CTL_PAD_DSE(strength));
|
||||
IOMUXC_SetPinConfig(IOMUXC_GPIO_SD_B1_03_USDHC2_DATA0,
|
||||
IOMUXC_SW_PAD_CTL_PAD_SPEED(speed) | IOMUXC_SW_PAD_CTL_PAD_SRE_MASK |
|
||||
IOMUXC_SW_PAD_CTL_PAD_PKE_MASK | IOMUXC_SW_PAD_CTL_PAD_PUE_MASK |
|
||||
IOMUXC_SW_PAD_CTL_PAD_HYS_MASK | IOMUXC_SW_PAD_CTL_PAD_PUS(1) |
|
||||
IOMUXC_SW_PAD_CTL_PAD_DSE(strength));
|
||||
IOMUXC_SetPinConfig(IOMUXC_GPIO_SD_B1_02_USDHC2_DATA1,
|
||||
IOMUXC_SW_PAD_CTL_PAD_SPEED(speed) | IOMUXC_SW_PAD_CTL_PAD_SRE_MASK |
|
||||
IOMUXC_SW_PAD_CTL_PAD_PKE_MASK | IOMUXC_SW_PAD_CTL_PAD_PUE_MASK |
|
||||
IOMUXC_SW_PAD_CTL_PAD_HYS_MASK | IOMUXC_SW_PAD_CTL_PAD_PUS(1) |
|
||||
IOMUXC_SW_PAD_CTL_PAD_DSE(strength));
|
||||
IOMUXC_SetPinConfig(IOMUXC_GPIO_SD_B1_01_USDHC2_DATA2,
|
||||
IOMUXC_SW_PAD_CTL_PAD_SPEED(speed) | IOMUXC_SW_PAD_CTL_PAD_SRE_MASK |
|
||||
IOMUXC_SW_PAD_CTL_PAD_PKE_MASK | IOMUXC_SW_PAD_CTL_PAD_PUE_MASK |
|
||||
IOMUXC_SW_PAD_CTL_PAD_HYS_MASK | IOMUXC_SW_PAD_CTL_PAD_PUS(1) |
|
||||
IOMUXC_SW_PAD_CTL_PAD_DSE(strength));
|
||||
IOMUXC_SetPinConfig(IOMUXC_GPIO_SD_B1_00_USDHC2_DATA3,
|
||||
IOMUXC_SW_PAD_CTL_PAD_SPEED(speed) | IOMUXC_SW_PAD_CTL_PAD_SRE_MASK |
|
||||
IOMUXC_SW_PAD_CTL_PAD_PKE_MASK | IOMUXC_SW_PAD_CTL_PAD_PUE_MASK |
|
||||
IOMUXC_SW_PAD_CTL_PAD_HYS_MASK | IOMUXC_SW_PAD_CTL_PAD_PUS(1) |
|
||||
IOMUXC_SW_PAD_CTL_PAD_DSE(strength));
|
||||
IOMUXC_SetPinConfig(IOMUXC_GPIO_SD_B1_08_USDHC2_DATA4,
|
||||
IOMUXC_SW_PAD_CTL_PAD_SPEED(speed) | IOMUXC_SW_PAD_CTL_PAD_SRE_MASK |
|
||||
IOMUXC_SW_PAD_CTL_PAD_PKE_MASK | IOMUXC_SW_PAD_CTL_PAD_PUE_MASK |
|
||||
IOMUXC_SW_PAD_CTL_PAD_HYS_MASK | IOMUXC_SW_PAD_CTL_PAD_PUS(1) |
|
||||
IOMUXC_SW_PAD_CTL_PAD_DSE(strength));
|
||||
IOMUXC_SetPinConfig(IOMUXC_GPIO_SD_B1_09_USDHC2_DATA5,
|
||||
IOMUXC_SW_PAD_CTL_PAD_SPEED(speed) | IOMUXC_SW_PAD_CTL_PAD_SRE_MASK |
|
||||
IOMUXC_SW_PAD_CTL_PAD_PKE_MASK | IOMUXC_SW_PAD_CTL_PAD_PUE_MASK |
|
||||
IOMUXC_SW_PAD_CTL_PAD_HYS_MASK | IOMUXC_SW_PAD_CTL_PAD_PUS(1) |
|
||||
IOMUXC_SW_PAD_CTL_PAD_DSE(strength));
|
||||
IOMUXC_SetPinConfig(IOMUXC_GPIO_SD_B1_10_USDHC2_DATA6,
|
||||
IOMUXC_SW_PAD_CTL_PAD_SPEED(speed) | IOMUXC_SW_PAD_CTL_PAD_SRE_MASK |
|
||||
IOMUXC_SW_PAD_CTL_PAD_PKE_MASK | IOMUXC_SW_PAD_CTL_PAD_PUE_MASK |
|
||||
IOMUXC_SW_PAD_CTL_PAD_HYS_MASK | IOMUXC_SW_PAD_CTL_PAD_PUS(1) |
|
||||
IOMUXC_SW_PAD_CTL_PAD_DSE(strength));
|
||||
IOMUXC_SetPinConfig(IOMUXC_GPIO_SD_B1_11_USDHC2_DATA7,
|
||||
IOMUXC_SW_PAD_CTL_PAD_SPEED(speed) | IOMUXC_SW_PAD_CTL_PAD_SRE_MASK |
|
||||
IOMUXC_SW_PAD_CTL_PAD_PKE_MASK | IOMUXC_SW_PAD_CTL_PAD_PUE_MASK |
|
||||
IOMUXC_SW_PAD_CTL_PAD_HYS_MASK | IOMUXC_SW_PAD_CTL_PAD_PUS(1) |
|
||||
IOMUXC_SW_PAD_CTL_PAD_DSE(strength));
|
||||
}
|
||||
|
||||
/* MPU configuration. */
|
||||
static void BOARD_ConfigMPU(void)
|
||||
void BOARD_ConfigMPU(void)
|
||||
{
|
||||
/* Disable I cache and D cache */
|
||||
SCB_DisableICache();
|
||||
SCB_DisableDCache();
|
||||
if (SCB_CCR_IC_Msk == (SCB_CCR_IC_Msk & SCB->CCR))
|
||||
{
|
||||
SCB_DisableICache();
|
||||
}
|
||||
if (SCB_CCR_DC_Msk == (SCB_CCR_DC_Msk & SCB->CCR))
|
||||
{
|
||||
SCB_DisableDCache();
|
||||
}
|
||||
|
||||
/* Disable MPU */
|
||||
ARM_MPU_Disable();
|
||||
|
||||
/* Region 0 setting */
|
||||
/* MPU configure:
|
||||
* Use ARM_MPU_RASR(DisableExec, AccessPermission, TypeExtField, IsShareable, IsCacheable, IsBufferable,
|
||||
* SubRegionDisable, Size)
|
||||
* API in mpu_armv7.h.
|
||||
* param DisableExec Instruction access (XN) disable bit,0=instruction fetches enabled, 1=instruction fetches
|
||||
* disabled.
|
||||
* param AccessPermission Data access permissions, allows you to configure read/write access for User and
|
||||
* Privileged mode.
|
||||
* Use MACROS defined in mpu_armv7.h:
|
||||
* ARM_MPU_AP_NONE/ARM_MPU_AP_PRIV/ARM_MPU_AP_URO/ARM_MPU_AP_FULL/ARM_MPU_AP_PRO/ARM_MPU_AP_RO
|
||||
* Combine TypeExtField/IsShareable/IsCacheable/IsBufferable to configure MPU memory access attributes.
|
||||
* TypeExtField IsShareable IsCacheable IsBufferable Memory Attribtue Shareability Cache
|
||||
* 0 x 0 0 Strongly Ordered shareable
|
||||
* 0 x 0 1 Device shareable
|
||||
* 0 0 1 0 Normal not shareable Outer and inner write
|
||||
* through no write allocate
|
||||
* 0 0 1 1 Normal not shareable Outer and inner write
|
||||
* back no write allocate
|
||||
* 0 1 1 0 Normal shareable Outer and inner write
|
||||
* through no write allocate
|
||||
* 0 1 1 1 Normal shareable Outer and inner write
|
||||
* back no write allocate
|
||||
* 1 0 0 0 Normal not shareable outer and inner
|
||||
* noncache
|
||||
* 1 1 0 0 Normal shareable outer and inner
|
||||
* noncache
|
||||
* 1 0 1 1 Normal not shareable outer and inner write
|
||||
* back write/read acllocate
|
||||
* 1 1 1 1 Normal shareable outer and inner write
|
||||
* back write/read acllocate
|
||||
* 2 x 0 0 Device not shareable
|
||||
* Above are normal use settings, if your want to see more details or want to config different inner/outter cache
|
||||
* policy.
|
||||
* please refer to Table 4-55 /4-56 in arm cortex-M7 generic user guide <dui0646b_cortex_m7_dgug.pdf>
|
||||
* param SubRegionDisable Sub-region disable field. 0=sub-region is enabled, 1=sub-region is disabled.
|
||||
* param Size Region size of the region to be configured. use ARM_MPU_REGION_SIZE_xxx MACRO in
|
||||
* mpu_armv7.h.
|
||||
*/
|
||||
|
||||
/* Region 0 setting: Memory with Device type, not shareable, non-cacheable. */
|
||||
MPU->RBAR = ARM_MPU_RBAR(0, 0xC0000000U);
|
||||
MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 2, 0, 0, 0, 0, ARM_MPU_REGION_SIZE_512MB);
|
||||
|
||||
/* Region 1 setting */
|
||||
/* Region 1 setting: Memory with Device type, not shareable, non-cacheable. */
|
||||
MPU->RBAR = ARM_MPU_RBAR(1, 0x80000000U);
|
||||
MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 2, 0, 0, 0, 0, ARM_MPU_REGION_SIZE_1GB);
|
||||
|
||||
/* Region 2 setting */
|
||||
// spi flash: normal type, cacheable, no bufferable, no shareable
|
||||
/* Region 2 setting */
|
||||
#if defined(XIP_EXTERNAL_FLASH) && (XIP_EXTERNAL_FLASH == 1)
|
||||
/* Setting Memory with Normal type, not shareable, outer/inner write back. */
|
||||
MPU->RBAR = ARM_MPU_RBAR(2, 0x60000000U);
|
||||
MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 0, 0, 1, 0, 0, ARM_MPU_REGION_SIZE_512MB);
|
||||
MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_RO, 0, 0, 1, 1, 0, ARM_MPU_REGION_SIZE_64MB);
|
||||
#else
|
||||
/* Setting Memory with Device type, not shareable, non-cacheable. */
|
||||
MPU->RBAR = ARM_MPU_RBAR(2, 0x60000000U);
|
||||
MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_RO, 2, 0, 0, 0, 0, ARM_MPU_REGION_SIZE_64MB);
|
||||
#endif
|
||||
|
||||
/* Region 3 setting */
|
||||
/* Region 3 setting: Memory with Device type, not shareable, non-cacheable. */
|
||||
MPU->RBAR = ARM_MPU_RBAR(3, 0x00000000U);
|
||||
MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 2, 0, 0, 0, 0, ARM_MPU_REGION_SIZE_1GB);
|
||||
|
||||
/* Region 4 setting */
|
||||
/* Region 4 setting: Memory with Normal type, not shareable, outer/inner write back */
|
||||
MPU->RBAR = ARM_MPU_RBAR(4, 0x00000000U);
|
||||
MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 0, 0, 1, 1, 0, ARM_MPU_REGION_SIZE_128KB);
|
||||
|
||||
/* Region 5 setting */
|
||||
/* Region 5 setting: Memory with Normal type, not shareable, outer/inner write back */
|
||||
MPU->RBAR = ARM_MPU_RBAR(5, 0x20000000U);
|
||||
MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 0, 0, 1, 1, 0, ARM_MPU_REGION_SIZE_128KB);
|
||||
|
||||
/* Region 6 setting */
|
||||
/* Region 6 setting: Memory with Normal type, not shareable, outer/inner write back */
|
||||
MPU->RBAR = ARM_MPU_RBAR(6, 0x20200000U);
|
||||
MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 0, 0, 1, 1, 0, ARM_MPU_REGION_SIZE_256KB);
|
||||
|
||||
#if defined(BSP_USING_SDRAM)
|
||||
/* Region 7 setting */
|
||||
/* The define sets the cacheable memory to shareable,
|
||||
* this suggestion is referred from chapter 2.2.1 Memory regions,
|
||||
* types and attributes in Cortex-M7 Devices, Generic User Guide */
|
||||
#if defined(SDRAM_IS_SHAREABLE)
|
||||
/* Region 7 setting: Memory with Normal type, shareable, outer/inner write back */
|
||||
MPU->RBAR = ARM_MPU_RBAR(7, 0x80000000U);
|
||||
MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 0, 1, 1, 1, 0, ARM_MPU_REGION_SIZE_32MB);
|
||||
#else
|
||||
/* Region 7 setting: Memory with Normal type, not shareable, outer/inner write back */
|
||||
MPU->RBAR = ARM_MPU_RBAR(7, 0x80000000U);
|
||||
MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 0, 0, 1, 1, 0, ARM_MPU_REGION_SIZE_32MB);
|
||||
|
||||
/* Region 8 setting */
|
||||
MPU->RBAR = ARM_MPU_RBAR(8, 0x81E00000U);
|
||||
MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 1, 1, 0, 0, 0, ARM_MPU_REGION_SIZE_2MB);
|
||||
#endif
|
||||
|
||||
/* Region 8 setting, set last 2MB of SDRAM can't be accessed by cache, glocal variables which are not expected to be
|
||||
* accessed by cache can be put here */
|
||||
/* Memory with Normal type, not shareable, non-cacheable */
|
||||
MPU->RBAR = ARM_MPU_RBAR(8, 0x81E00000U);
|
||||
MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 1, 0, 0, 0, 0, ARM_MPU_REGION_SIZE_2MB);
|
||||
|
||||
/* Enable MPU */
|
||||
ARM_MPU_Enable(MPU_CTRL_PRIVDEFENA_Msk);
|
||||
|
||||
@@ -168,8 +597,10 @@ void InitBoardHardware()
|
||||
BOARD_InitPins();
|
||||
BOARD_BootClockRUN();
|
||||
|
||||
#ifndef BSP_USING_LWIP
|
||||
NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4);
|
||||
SysTick_Config(SystemCoreClock / TICK_PER_SECOND);
|
||||
#endif
|
||||
|
||||
#ifdef BSP_USING_LPUART
|
||||
imxrt_uart_pins_init();
|
||||
@@ -177,8 +608,13 @@ void InitBoardHardware()
|
||||
|
||||
InitBoardMemory((void *)HEAP_BEGIN, (void *)HEAP_END);
|
||||
|
||||
Imrt1052HwUartInit();
|
||||
#ifdef BSP_USING_LWIP
|
||||
ETH_BSP_Config();
|
||||
#endif
|
||||
|
||||
#ifdef BSP_USING_LPUART
|
||||
Imrt1052HwUartInit();
|
||||
#endif
|
||||
InstallConsole(KERNEL_CONSOLE_BUS_NAME, KERNEL_CONSOLE_DRV_NAME, KERNEL_CONSOLE_DEVICE_NAME);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,11 @@
|
||||
/*
|
||||
* Copyright 2017-2018 NXP
|
||||
* All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* Copyright (c) 2020 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
@@ -13,7 +21,7 @@
|
||||
/**
|
||||
* @file board.h
|
||||
* @brief define imxrt1052-board init configure and start-up function
|
||||
* @version 1.0
|
||||
* @version 1.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2021-05-28
|
||||
*/
|
||||
@@ -21,11 +29,11 @@
|
||||
/*************************************************
|
||||
File name: board.h
|
||||
Description: define imxrt1052-board board init function and struct
|
||||
Others:
|
||||
History:
|
||||
Others:
|
||||
History:
|
||||
1. Date: 2021-05-28
|
||||
Author: AIIT XUOS Lab
|
||||
Modification:
|
||||
Modification:
|
||||
1. define imxrt-board InitBoardHardware
|
||||
2. define imxrt-board heap struct
|
||||
*************************************************/
|
||||
@@ -34,19 +42,282 @@ Modification:
|
||||
#define __BOARD_H__
|
||||
|
||||
#include "fsl_common.h"
|
||||
#include "fsl_gpio.h"
|
||||
#include "fsl_clock.h"
|
||||
#include "fsl_enet.h"
|
||||
#include "clock_config.h"
|
||||
#include <xiuos.h>
|
||||
#include <arch_interrupt.h>
|
||||
#include "enet_ethernetif.h"
|
||||
|
||||
extern int heap_start;
|
||||
extern int heap_end;
|
||||
#define HEAP_BEGIN (&heap_start)
|
||||
#define HEAP_END (&heap_end)
|
||||
|
||||
|
||||
#define HEAP_SIZE ((uint32_t)HEAP_END - (uint32_t)HEAP_BEGIN)
|
||||
|
||||
void InitBoardHardware(void);
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
/*! @brief The board name */
|
||||
#define BOARD_NAME "IMXRT1050-EVKB"
|
||||
|
||||
/* The UART to use for debug messages. */
|
||||
#define BOARD_DEBUG_UART_TYPE kSerialPort_Uart
|
||||
#define BOARD_DEBUG_UART_BASEADDR (uint32_t) LPUART1
|
||||
#define BOARD_DEBUG_UART_INSTANCE 1U
|
||||
|
||||
#define BOARD_DEBUG_UART_CLK_FREQ BOARD_DebugConsoleSrcFreq()
|
||||
|
||||
#define BOARD_UART_IRQ LPUART1_IRQn
|
||||
#define BOARD_UART_IRQ_HANDLER LPUART1_IRQHandler
|
||||
|
||||
#ifndef BOARD_DEBUG_UART_BAUDRATE
|
||||
#define BOARD_DEBUG_UART_BAUDRATE (115200U)
|
||||
#endif /* BOARD_DEBUG_UART_BAUDRATE */
|
||||
|
||||
/*! @brief The USER_LED used for board */
|
||||
#define LOGIC_LED_ON (0U)
|
||||
#define LOGIC_LED_OFF (1U)
|
||||
#ifndef BOARD_USER_LED_GPIO
|
||||
#define BOARD_USER_LED_GPIO GPIO1
|
||||
#endif
|
||||
#ifndef BOARD_USER_LED_GPIO_PIN
|
||||
#define BOARD_USER_LED_GPIO_PIN (9U)
|
||||
#endif
|
||||
|
||||
#define USER_LED_INIT(output) \
|
||||
GPIO_PinWrite(BOARD_USER_LED_GPIO, BOARD_USER_LED_GPIO_PIN, output); \
|
||||
BOARD_USER_LED_GPIO->GDIR |= (1U << BOARD_USER_LED_GPIO_PIN) /*!< Enable target USER_LED */
|
||||
#define USER_LED_ON() \
|
||||
GPIO_PortClear(BOARD_USER_LED_GPIO, 1U << BOARD_USER_LED_GPIO_PIN) /*!< Turn off target USER_LED */
|
||||
#define USER_LED_OFF() GPIO_PortSet(BOARD_USER_LED_GPIO, 1U << BOARD_USER_LED_GPIO_PIN) /*!<Turn on target USER_LED*/
|
||||
#define USER_LED_TOGGLE() \
|
||||
GPIO_PinWrite(BOARD_USER_LED_GPIO, BOARD_USER_LED_GPIO_PIN, \
|
||||
0x1 ^ GPIO_PinRead(BOARD_USER_LED_GPIO, BOARD_USER_LED_GPIO_PIN)) /*!< Toggle target USER_LED */
|
||||
|
||||
/*! @brief Define the port interrupt number for the board switches */
|
||||
#ifndef BOARD_USER_BUTTON_GPIO
|
||||
#define BOARD_USER_BUTTON_GPIO GPIO5
|
||||
#endif
|
||||
#ifndef BOARD_USER_BUTTON_GPIO_PIN
|
||||
#define BOARD_USER_BUTTON_GPIO_PIN (0U)
|
||||
#endif
|
||||
#define BOARD_USER_BUTTON_IRQ GPIO5_Combined_0_15_IRQn
|
||||
#define BOARD_USER_BUTTON_IRQ_HANDLER GPIO5_Combined_0_15_IRQHandler
|
||||
#define BOARD_USER_BUTTON_NAME "SW8"
|
||||
|
||||
/*! @brief The hyper flash size */
|
||||
#define BOARD_FLASH_SIZE (0x4000000U)
|
||||
|
||||
/*! @brief The ENET PHY address. */
|
||||
#define BOARD_ENET0_PHY_ADDRESS (0x02U) /* Phy address of enet port 0. */
|
||||
|
||||
/* USB PHY condfiguration */
|
||||
#define BOARD_USB_PHY_D_CAL (0x0CU)
|
||||
#define BOARD_USB_PHY_TXCAL45DP (0x06U)
|
||||
#define BOARD_USB_PHY_TXCAL45DM (0x06U)
|
||||
|
||||
#define BOARD_ARDUINO_INT_IRQ (GPIO1_INT3_IRQn)
|
||||
#define BOARD_ARDUINO_I2C_IRQ (LPI2C1_IRQn)
|
||||
#define BOARD_ARDUINO_I2C_INDEX (1)
|
||||
#define BOARD_USDHC1_BASEADDR USDHC1
|
||||
#define BOARD_USDHC2_BASEADDR USDHC2
|
||||
#define BOARD_USDHC_CD_GPIO_BASE GPIO2
|
||||
#define BOARD_USDHC_CD_GPIO_PIN 28
|
||||
#define BOARD_USDHC_CD_PORT_IRQ GPIO2_Combined_16_31_IRQn
|
||||
#define BOARD_USDHC_CD_PORT_IRQ_HANDLER GPIO2_Combined_16_31_IRQHandler
|
||||
|
||||
#define BOARD_USDHC_CD_STATUS() (GPIO_PinRead(BOARD_USDHC_CD_GPIO_BASE, BOARD_USDHC_CD_GPIO_PIN))
|
||||
|
||||
#define BOARD_USDHC_CD_INTERRUPT_STATUS() (GPIO_PortGetInterruptFlags(BOARD_USDHC_CD_GPIO_BASE))
|
||||
#define BOARD_USDHC_CD_CLEAR_INTERRUPT(flag) (GPIO_PortClearInterruptFlags(BOARD_USDHC_CD_GPIO_BASE, flag))
|
||||
|
||||
#define BOARD_USDHC_CD_GPIO_INIT() \
|
||||
{ \
|
||||
gpio_pin_config_t sw_config = { \
|
||||
kGPIO_DigitalInput, \
|
||||
0, \
|
||||
kGPIO_IntRisingOrFallingEdge, \
|
||||
}; \
|
||||
GPIO_PinInit(BOARD_USDHC_CD_GPIO_BASE, BOARD_USDHC_CD_GPIO_PIN, &sw_config); \
|
||||
GPIO_PortEnableInterrupts(BOARD_USDHC_CD_GPIO_BASE, 1U << BOARD_USDHC_CD_GPIO_PIN); \
|
||||
GPIO_PortClearInterruptFlags(BOARD_USDHC_CD_GPIO_BASE, ~0); \
|
||||
}
|
||||
#define BOARD_HAS_SDCARD (1U)
|
||||
#define BOARD_SD_POWER_RESET_GPIO (GPIO1)
|
||||
#define BOARD_SD_POWER_RESET_GPIO_PIN (5U)
|
||||
|
||||
#define BOARD_USDHC_CARD_INSERT_CD_LEVEL (0U)
|
||||
|
||||
#define BOARD_USDHC_MMCCARD_POWER_CONTROL(state)
|
||||
|
||||
#define BOARD_USDHC_MMCCARD_POWER_CONTROL_INIT() \
|
||||
{ \
|
||||
gpio_pin_config_t sw_config = { \
|
||||
kGPIO_DigitalOutput, \
|
||||
0, \
|
||||
kGPIO_NoIntmode, \
|
||||
}; \
|
||||
GPIO_PinInit(BOARD_SD_POWER_RESET_GPIO, BOARD_SD_POWER_RESET_GPIO_PIN, &sw_config); \
|
||||
GPIO_PinWrite(BOARD_SD_POWER_RESET_GPIO, BOARD_SD_POWER_RESET_GPIO_PIN, true); \
|
||||
}
|
||||
|
||||
#define BOARD_USDHC_SDCARD_POWER_CONTROL_INIT() \
|
||||
{ \
|
||||
gpio_pin_config_t sw_config = { \
|
||||
kGPIO_DigitalOutput, \
|
||||
0, \
|
||||
kGPIO_NoIntmode, \
|
||||
}; \
|
||||
GPIO_PinInit(BOARD_SD_POWER_RESET_GPIO, BOARD_SD_POWER_RESET_GPIO_PIN, &sw_config); \
|
||||
}
|
||||
|
||||
#define BOARD_USDHC_SDCARD_POWER_CONTROL(state) \
|
||||
(GPIO_PinWrite(BOARD_SD_POWER_RESET_GPIO, BOARD_SD_POWER_RESET_GPIO_PIN, state))
|
||||
|
||||
#define BOARD_USDHC1_CLK_FREQ (CLOCK_GetSysPfdFreq(kCLOCK_Pfd0) / (CLOCK_GetDiv(kCLOCK_Usdhc1Div) + 1U))
|
||||
#define BOARD_USDHC2_CLK_FREQ (CLOCK_GetSysPfdFreq(kCLOCK_Pfd0) / (CLOCK_GetDiv(kCLOCK_Usdhc2Div) + 1U))
|
||||
|
||||
#define BOARD_SD_HOST_BASEADDR BOARD_USDHC1_BASEADDR
|
||||
#define BOARD_SD_HOST_CLK_FREQ BOARD_USDHC1_CLK_FREQ
|
||||
#define BOARD_SD_HOST_IRQ USDHC1_IRQn
|
||||
|
||||
#define BOARD_MMC_HOST_BASEADDR BOARD_USDHC2_BASEADDR
|
||||
#define BOARD_MMC_HOST_CLK_FREQ BOARD_USDHC2_CLK_FREQ
|
||||
#define BOARD_MMC_HOST_IRQ USDHC2_IRQn
|
||||
#define BOARD_MMC_VCCQ_SUPPLY kMMC_VoltageWindow170to195
|
||||
#define BOARD_MMC_VCC_SUPPLY kMMC_VoltageWindows270to360
|
||||
/* we are using the BB SD socket to DEMO the MMC example,but the
|
||||
* SD socket provide 4bit bus only, so we define this macro to avoid
|
||||
* 8bit data bus test
|
||||
*/
|
||||
#define BOARD_MMC_SUPPORT_8BIT_BUS (1U)
|
||||
|
||||
#define BOARD_SD_HOST_SUPPORT_SDR104_FREQ (200000000U)
|
||||
#define BOARD_SD_HOST_SUPPORT_HS200_FREQ (180000000U)
|
||||
|
||||
/*! @brief The WIFI-QCA shield pin. */
|
||||
#define BOARD_INITGT202SHIELD_PWRON_GPIO GPIO1 /*!< GPIO device name: GPIO */
|
||||
#define BOARD_INITGT202SHIELD_PWRON_PORT 1U /*!< PORT device index: 1 */
|
||||
#define BOARD_INITGT202SHIELD_PWRON_GPIO_PIN 3U /*!< PIO4 pin index: 3 */
|
||||
#define BOARD_INITGT202SHIELD_PWRON_PIN_NAME GPIO1_3 /*!< Pin name */
|
||||
#define BOARD_INITGT202SHIELD_PWRON_LABEL "PWRON" /*!< Label */
|
||||
#define BOARD_INITGT202SHIELD_PWRON_NAME "PWRON" /*!< Identifier name */
|
||||
#define BOARD_INITGT202SHIELD_PWRON_DIRECTION kGPIO_DigitalOutput /*!< Direction */
|
||||
|
||||
#define BOARD_INITGT202SHIELD_IRQ_GPIO GPIO1 /*!< GPIO device name: GPIO */
|
||||
#define BOARD_INITGT202SHIELD_IRQ_PORT 1U /*!< PORT device index: 1 */
|
||||
#define BOARD_INITGT202SHIELD_IRQ_GPIO_PIN 19U /*!< PIO1 pin index: 19 */
|
||||
#define BOARD_INITGT202SHIELD_IRQ_PIN_NAME GPIO1_19 /*!< Pin name */
|
||||
#define BOARD_INITGT202SHIELD_IRQ_LABEL "IRQ" /*!< Label */
|
||||
#define BOARD_INITGT202SHIELD_IRQ_NAME "IRQ" /*!< Identifier name */
|
||||
#define BOARD_INITGT202SHIELD_IRQ_DIRECTION kGPIO_DigitalInput /*!< Direction */
|
||||
|
||||
/*! @brief The WIFI-QCA Silex 2401 shield pin. */
|
||||
#define BOARD_INITSILEX2401SHIELD_PWRON_GPIO GPIO1 /*!< GPIO device name: GPIO */
|
||||
#define BOARD_INITSILEX2401SHIELD_PWRON_PORT 1U /*!< PORT device index: 1 */
|
||||
#define BOARD_INITSILEX2401SHIELD_PWRON_GPIO_PIN 9U /*!< PIO4 pin index: 9 */
|
||||
#define BOARD_INITSILEX2401SHIELD_PWRON_PIN_NAME GPIO1_9 /*!< Pin name */
|
||||
#define BOARD_INITSILEX2401SHIELD_PWRON_LABEL "PWRON" /*!< Label */
|
||||
#define BOARD_INITSILEX2401SHIELD_PWRON_NAME "PWRON" /*!< Identifier name */
|
||||
#define BOARD_INITSILEX2401SHIELD_PWRON_DIRECTION kGPIO_DigitalOutput /*!< Direction */
|
||||
|
||||
#define BOARD_INITSILEX2401SHIELD_IRQ_GPIO GPIO1 /*!< GPIO device name: GPIO */
|
||||
#define BOARD_INITSILEX2401SHIELD_IRQ_PORT 1U /*!< PORT device index: 1 */
|
||||
#define BOARD_INITSILEX2401SHIELD_IRQ_GPIO_PIN 11U /*!< PIO1 pin index: 11 */
|
||||
#define BOARD_INITSILEX2401SHIELD_IRQ_PIN_NAME GPIO1_11 /*!< Pin name */
|
||||
#define BOARD_INITSILEX2401SHIELD_IRQ_LABEL "IRQ" /*!< Label */
|
||||
#define BOARD_INITSILEX2401SHIELD_IRQ_NAME "IRQ" /*!< Identifier name */
|
||||
#define BOARD_INITSILEX2401SHIELD_IRQ_DIRECTION kGPIO_DigitalInput /*!< Direction */
|
||||
|
||||
/* @Brief Board accelerator sensor configuration */
|
||||
#define BOARD_ACCEL_I2C_BASEADDR LPI2C1
|
||||
/* Select USB1 PLL (480 MHz) as LPI2C's clock source */
|
||||
#define BOARD_ACCEL_I2C_CLOCK_SOURCE_SELECT (0U)
|
||||
/* Clock divider for LPI2C clock source */
|
||||
#define BOARD_ACCEL_I2C_CLOCK_SOURCE_DIVIDER (5U)
|
||||
#define BOARD_ACCEL_I2C_CLOCK_FREQ (CLOCK_GetFreq(kCLOCK_Usb1PllClk) / 8 / (BOARD_ACCEL_I2C_CLOCK_SOURCE_DIVIDER + 1U))
|
||||
|
||||
#define BOARD_CODEC_I2C_BASEADDR LPI2C1
|
||||
#define BOARD_CODEC_I2C_INSTANCE 1U
|
||||
#define BOARD_CODEC_I2C_CLOCK_SOURCE_SELECT (0U)
|
||||
#define BOARD_CODEC_I2C_CLOCK_SOURCE_DIVIDER (5U)
|
||||
#define BOARD_CODEC_I2C_CLOCK_FREQ (10000000U)
|
||||
|
||||
/* @Brief Board CAMERA configuration */
|
||||
#define BOARD_CAMERA_I2C_BASEADDR LPI2C1
|
||||
#define BOARD_CAMERA_I2C_CLOCK_SOURCE_DIVIDER (5U)
|
||||
#define BOARD_CAMERA_I2C_CLOCK_SOURCE_SELECT (0U) /* Select USB1 PLL (480 MHz) as LPI2C's clock source */
|
||||
#define BOARD_CAMERA_I2C_CLOCK_FREQ \
|
||||
(CLOCK_GetFreq(kCLOCK_Usb1PllClk) / 8 / (BOARD_CAMERA_I2C_CLOCK_SOURCE_DIVIDER + 1U))
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/*******************************************************************************
|
||||
* API
|
||||
******************************************************************************/
|
||||
uint32_t BOARD_DebugConsoleSrcFreq(void);
|
||||
|
||||
void BOARD_InitDebugConsole(void);
|
||||
|
||||
void BOARD_ConfigMPU(void);
|
||||
#if defined(SDK_I2C_BASED_COMPONENT_USED) && SDK_I2C_BASED_COMPONENT_USED
|
||||
void BOARD_LPI2C_Init(LPI2C_Type *base, uint32_t clkSrc_Hz);
|
||||
status_t BOARD_LPI2C_Send(LPI2C_Type *base,
|
||||
uint8_t deviceAddress,
|
||||
uint32_t subAddress,
|
||||
uint8_t subaddressSize,
|
||||
uint8_t *txBuff,
|
||||
uint8_t txBuffSize);
|
||||
status_t BOARD_LPI2C_Receive(LPI2C_Type *base,
|
||||
uint8_t deviceAddress,
|
||||
uint32_t subAddress,
|
||||
uint8_t subaddressSize,
|
||||
uint8_t *rxBuff,
|
||||
uint8_t rxBuffSize);
|
||||
status_t BOARD_LPI2C_SendSCCB(LPI2C_Type *base,
|
||||
uint8_t deviceAddress,
|
||||
uint32_t subAddress,
|
||||
uint8_t subaddressSize,
|
||||
uint8_t *txBuff,
|
||||
uint8_t txBuffSize);
|
||||
status_t BOARD_LPI2C_ReceiveSCCB(LPI2C_Type *base,
|
||||
uint8_t deviceAddress,
|
||||
uint32_t subAddress,
|
||||
uint8_t subaddressSize,
|
||||
uint8_t *rxBuff,
|
||||
uint8_t rxBuffSize);
|
||||
void BOARD_Accel_I2C_Init(void);
|
||||
status_t BOARD_Accel_I2C_Send(uint8_t deviceAddress, uint32_t subAddress, uint8_t subaddressSize, uint32_t txBuff);
|
||||
status_t BOARD_Accel_I2C_Receive(
|
||||
uint8_t deviceAddress, uint32_t subAddress, uint8_t subaddressSize, uint8_t *rxBuff, uint8_t rxBuffSize);
|
||||
void BOARD_Codec_I2C_Init(void);
|
||||
status_t BOARD_Codec_I2C_Send(
|
||||
uint8_t deviceAddress, uint32_t subAddress, uint8_t subAddressSize, const uint8_t *txBuff, uint8_t txBuffSize);
|
||||
status_t BOARD_Codec_I2C_Receive(
|
||||
uint8_t deviceAddress, uint32_t subAddress, uint8_t subAddressSize, uint8_t *rxBuff, uint8_t rxBuffSize);
|
||||
void BOARD_Camera_I2C_Init(void);
|
||||
status_t BOARD_Camera_I2C_Send(
|
||||
uint8_t deviceAddress, uint32_t subAddress, uint8_t subAddressSize, const uint8_t *txBuff, uint8_t txBuffSize);
|
||||
status_t BOARD_Camera_I2C_Receive(
|
||||
uint8_t deviceAddress, uint32_t subAddress, uint8_t subAddressSize, uint8_t *rxBuff, uint8_t rxBuffSize);
|
||||
|
||||
status_t BOARD_Camera_I2C_SendSCCB(
|
||||
uint8_t deviceAddress, uint32_t subAddress, uint8_t subAddressSize, const uint8_t *txBuff, uint8_t txBuffSize);
|
||||
status_t BOARD_Camera_I2C_ReceiveSCCB(
|
||||
uint8_t deviceAddress, uint32_t subAddress, uint8_t subAddressSize, uint8_t *rxBuff, uint8_t rxBuffSize);
|
||||
#endif /* SDK_I2C_BASED_COMPONENT_USED */
|
||||
void BOARD_SD_Pin_Config(uint32_t speed, uint32_t strength);
|
||||
void BOARD_MMC_Pin_Config(uint32_t speed, uint32_t strength);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* _BOARD_H_ */
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
/**
|
||||
* @file link.lds
|
||||
* @brief ok1052-c Linker script
|
||||
* @version 1.0
|
||||
* @version 1.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2021-05-28
|
||||
*/
|
||||
@@ -38,10 +38,10 @@
|
||||
File name: link.lds
|
||||
Description: ok1052-c Linker script
|
||||
Others: take MIMXRT1052xxxxx_flexspi_nor.ld for references
|
||||
History:
|
||||
History:
|
||||
1. Date: 2021-05-28
|
||||
Author: AIIT XUOS Lab
|
||||
Modification:
|
||||
Modification:
|
||||
1. add shell cmd table and g_service_table
|
||||
*************************************************/
|
||||
|
||||
@@ -57,7 +57,7 @@ MEMORY
|
||||
m_interrupts (RX) : ORIGIN = 0x60002000, LENGTH = 0x00000400
|
||||
m_text (RX) : ORIGIN = 0x60002400, LENGTH = 0x03FFDC00
|
||||
m_data (RW) : ORIGIN = 0x20000000, LENGTH = 0x00020000
|
||||
m_data2 (RW) : ORIGIN = 0x20200000, LENGTH = 0x00040000
|
||||
m_data2 (RW) : ORIGIN = 0x20200000, LENGTH = 0x00060000
|
||||
}
|
||||
|
||||
/* Define output sections */
|
||||
@@ -241,9 +241,9 @@ SECTIONS
|
||||
stack_end = .;
|
||||
__StackTop = .;
|
||||
heap_start = .;
|
||||
} > m_data
|
||||
} > m_data2
|
||||
|
||||
PROVIDE(heap_end = ORIGIN(m_data) + LENGTH(m_data));
|
||||
PROVIDE(heap_end = ORIGIN(m_data2) + LENGTH(m_data2));
|
||||
|
||||
.ARM.attributes 0 : { *(.ARM.attributes) }
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
/**
|
||||
* @file pin_mux.c
|
||||
* @brief support imxrt1052-board pin configure
|
||||
* @version 1.0
|
||||
* @version 1.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2021-05-29
|
||||
*/
|
||||
@@ -21,7 +21,7 @@
|
||||
/*
|
||||
* TEXT BELOW IS USED AS SETTING FOR TOOLS *************************************
|
||||
!!GlobalInfo
|
||||
product: Pins v5.0
|
||||
product: Pins v4.1
|
||||
processor: MIMXRT1052xxxxB
|
||||
package_id: MIMXRT1052DVL6B
|
||||
mcu_data: ksdk2_0
|
||||
@@ -37,22 +37,48 @@ pin_labels:
|
||||
#include "pin_mux.h"
|
||||
|
||||
/* FUNCTION ************************************************************************************************************
|
||||
*
|
||||
*
|
||||
* Function Name : BOARD_InitBootPins
|
||||
* Description : Calls initialization functions.
|
||||
*
|
||||
*
|
||||
* END ****************************************************************************************************************/
|
||||
void BOARD_InitBootPins(void) {
|
||||
BOARD_InitPins();
|
||||
}
|
||||
|
||||
/*
|
||||
* TEXT BELOW IS USED AS SETTING FOR TOOLS *************************************
|
||||
BOARD_InitPins:
|
||||
- options: {callFromInitBoot: 'false', coreID: core0, enableClock: 'true'}
|
||||
- options: {callFromInitBoot: 'true', coreID: core0, enableClock: 'true'}
|
||||
- pin_list:
|
||||
- {pin_num: L14, peripheral: LPUART1, signal: RX, pin_signal: GPIO_AD_B0_13}
|
||||
- {pin_num: K14, peripheral: LPUART1, signal: TX, pin_signal: GPIO_AD_B0_12}
|
||||
- {pin_num: F14, peripheral: GPIO1, signal: 'gpio_io, 09', pin_signal: GPIO_AD_B0_09}
|
||||
- {pin_num: L14, peripheral: LPUART1, signal: RX, pin_signal: GPIO_AD_B0_13, software_input_on: Disable, hysteresis_enable: Disable, pull_up_down_config: Pull_Down_100K_Ohm,
|
||||
pull_keeper_select: Keeper, pull_keeper_enable: Enable, open_drain: Disable, speed: MHZ_100, drive_strength: R0_6, slew_rate: Slow}
|
||||
- {pin_num: K14, peripheral: LPUART1, signal: TX, pin_signal: GPIO_AD_B0_12, software_input_on: Disable, hysteresis_enable: Disable, pull_up_down_config: Pull_Down_100K_Ohm,
|
||||
pull_keeper_select: Keeper, pull_keeper_enable: Enable, open_drain: Disable, speed: MHZ_100, drive_strength: R0_6, slew_rate: Slow}
|
||||
- {pin_num: A7, peripheral: ENET, signal: enet_mdc, pin_signal: GPIO_EMC_40, software_input_on: Disable, hysteresis_enable: Disable, pull_up_down_config: Pull_Up_100K_Ohm,
|
||||
pull_keeper_select: Pull, pull_keeper_enable: Enable, open_drain: Disable, speed: MHZ_200, drive_strength: R0_5, slew_rate: Fast}
|
||||
- {pin_num: C7, peripheral: ENET, signal: enet_mdio, pin_signal: GPIO_EMC_41, software_input_on: Disable, hysteresis_enable: Disable, pull_up_down_config: Pull_Up_100K_Ohm,
|
||||
pull_keeper_select: Pull, pull_keeper_enable: Enable, open_drain: Enable, speed: MHZ_50, drive_strength: R0_5, slew_rate: Fast}
|
||||
- {pin_num: B13, peripheral: ENET, signal: enet_ref_clk, pin_signal: GPIO_B1_10, software_input_on: Enable, hysteresis_enable: Disable, pull_up_down_config: Pull_Down_100K_Ohm,
|
||||
pull_keeper_select: Keeper, pull_keeper_enable: Disable, open_drain: Disable, speed: MHZ_50, drive_strength: R0_6, slew_rate: Fast}
|
||||
- {pin_num: E12, peripheral: ENET, signal: 'enet_rx_data, 0', pin_signal: GPIO_B1_04, software_input_on: Disable, hysteresis_enable: Disable, pull_up_down_config: Pull_Up_100K_Ohm,
|
||||
pull_keeper_select: Pull, pull_keeper_enable: Enable, open_drain: Disable, speed: MHZ_200, drive_strength: R0_5, slew_rate: Fast}
|
||||
- {pin_num: D12, peripheral: ENET, signal: 'enet_rx_data, 1', pin_signal: GPIO_B1_05, software_input_on: Disable, hysteresis_enable: Disable, pull_up_down_config: Pull_Up_100K_Ohm,
|
||||
pull_keeper_select: Pull, pull_keeper_enable: Enable, open_drain: Disable, speed: MHZ_200, drive_strength: R0_5, slew_rate: Fast}
|
||||
- {pin_num: C12, peripheral: ENET, signal: enet_rx_en, pin_signal: GPIO_B1_06, software_input_on: Disable, hysteresis_enable: Disable, pull_up_down_config: Pull_Up_100K_Ohm,
|
||||
pull_keeper_select: Pull, pull_keeper_enable: Enable, open_drain: Disable, speed: MHZ_200, drive_strength: R0_5, slew_rate: Fast}
|
||||
- {pin_num: C13, peripheral: ENET, signal: enet_rx_er, pin_signal: GPIO_B1_11, software_input_on: Disable, hysteresis_enable: Disable, pull_up_down_config: Pull_Up_100K_Ohm,
|
||||
pull_keeper_select: Pull, pull_keeper_enable: Enable, open_drain: Disable, speed: MHZ_200, drive_strength: R0_5, slew_rate: Fast}
|
||||
- {pin_num: B12, peripheral: ENET, signal: 'enet_tx_data, 0', pin_signal: GPIO_B1_07, software_input_on: Disable, hysteresis_enable: Disable, pull_up_down_config: Pull_Up_100K_Ohm,
|
||||
pull_keeper_select: Pull, pull_keeper_enable: Enable, open_drain: Disable, speed: MHZ_200, drive_strength: R0_5, slew_rate: Fast}
|
||||
- {pin_num: A12, peripheral: ENET, signal: 'enet_tx_data, 1', pin_signal: GPIO_B1_08, software_input_on: Disable, hysteresis_enable: Disable, pull_up_down_config: Pull_Up_100K_Ohm,
|
||||
pull_keeper_select: Pull, pull_keeper_enable: Enable, open_drain: Disable, speed: MHZ_200, drive_strength: R0_5, slew_rate: Fast}
|
||||
- {pin_num: A13, peripheral: ENET, signal: enet_tx_en, pin_signal: GPIO_B1_09, software_input_on: Disable, hysteresis_enable: Disable, pull_up_down_config: Pull_Up_100K_Ohm,
|
||||
pull_keeper_select: Pull, pull_keeper_enable: Enable, open_drain: Disable, speed: MHZ_200, drive_strength: R0_5, slew_rate: Fast}
|
||||
- {pin_num: F14, peripheral: GPIO1, signal: 'gpio_io, 09', pin_signal: GPIO_AD_B0_09, software_input_on: Disable, hysteresis_enable: Disable, pull_up_down_config: Pull_Up_100K_Ohm,
|
||||
pull_keeper_select: Pull, pull_keeper_enable: Enable, open_drain: Disable, speed: MHZ_100, drive_strength: R0_5, slew_rate: Fast}
|
||||
- {pin_num: G13, peripheral: GPIO1, signal: 'gpio_io, 10', pin_signal: GPIO_AD_B0_10, software_input_on: Disable, hysteresis_enable: Disable, pull_up_down_config: Pull_Up_100K_Ohm,
|
||||
pull_keeper_select: Pull, pull_keeper_enable: Enable, open_drain: Disable, speed: MHZ_100, drive_strength: R0_5, slew_rate: Fast}
|
||||
* BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS ***********
|
||||
*/
|
||||
|
||||
@@ -63,17 +89,214 @@ BOARD_InitPins:
|
||||
*
|
||||
* END ****************************************************************************************************************/
|
||||
void BOARD_InitPins(void) {
|
||||
CLOCK_EnableClock(kCLOCK_Iomuxc); /* iomuxc clock (iomuxc_clk_enable): 0x03U */
|
||||
CLOCK_EnableClock(kCLOCK_Iomuxc); /* iomuxc clock (iomuxc_clk_enable): 0x03u */
|
||||
|
||||
// IOMUXC_SetPinMux(
|
||||
// IOMUXC_GPIO_AD_B0_09_GPIO1_IO09, /* GPIO_AD_B0_09 is configured as GPIO1_IO09 */
|
||||
// 0U); /* Software Input On Field: Input Path is determined by functionality */
|
||||
|
||||
|
||||
IOMUXC_SetPinMux(
|
||||
IOMUXC_GPIO_AD_B0_09_GPIO1_IO09, /* GPIO_AD_B0_09 is configured as GPIO1_IO09 */
|
||||
IOMUXC_GPIO_AD_B0_03_GPIO1_IO03, /* GPIO_AD_B0_09 is configured as GPIO1_IO09 */
|
||||
0U); /* Software Input On Field: Input Path is determined by functionality */
|
||||
IOMUXC_SetPinMux(
|
||||
IOMUXC_GPIO_AD_B0_10_GPIO1_IO10, /* GPIO_AD_B0_10 is configured as GPIO1_IO10 */
|
||||
0U); /* Software Input On Field: Input Path is determined by functionality */
|
||||
|
||||
IOMUXC_SetPinMux(
|
||||
IOMUXC_GPIO_AD_B0_12_LPUART1_TX, /* GPIO_AD_B0_12 is configured as LPUART1_TX */
|
||||
0U); /* Software Input On Field: Input Path is determined by functionality */
|
||||
IOMUXC_SetPinMux(
|
||||
IOMUXC_GPIO_AD_B0_13_LPUART1_RX, /* GPIO_AD_B0_13 is configured as LPUART1_RX */
|
||||
0U); /* Software Input On Field: Input Path is determined by functionality */
|
||||
|
||||
IOMUXC_SetPinMux(
|
||||
IOMUXC_GPIO_B1_04_ENET_RX_DATA00, /* GPIO_B1_04 is configured as ENET_RX_DATA00 */
|
||||
0U); /* Software Input On Field: Input Path is determined by functionality */
|
||||
IOMUXC_SetPinMux(
|
||||
IOMUXC_GPIO_B1_05_ENET_RX_DATA01, /* GPIO_B1_05 is configured as ENET_RX_DATA01 */
|
||||
0U); /* Software Input On Field: Input Path is determined by functionality */
|
||||
IOMUXC_SetPinMux(
|
||||
IOMUXC_GPIO_B1_06_ENET_RX_EN, /* GPIO_B1_06 is configured as ENET_RX_EN */
|
||||
0U); /* Software Input On Field: Input Path is determined by functionality */
|
||||
IOMUXC_SetPinMux(
|
||||
IOMUXC_GPIO_B1_07_ENET_TX_DATA00, /* GPIO_B1_07 is configured as ENET_TX_DATA00 */
|
||||
0U); /* Software Input On Field: Input Path is determined by functionality */
|
||||
IOMUXC_SetPinMux(
|
||||
IOMUXC_GPIO_B1_08_ENET_TX_DATA01, /* GPIO_B1_08 is configured as ENET_TX_DATA01 */
|
||||
0U); /* Software Input On Field: Input Path is determined by functionality */
|
||||
IOMUXC_SetPinMux(
|
||||
IOMUXC_GPIO_B1_09_ENET_TX_EN, /* GPIO_B1_09 is configured as ENET_TX_EN */
|
||||
0U); /* Software Input On Field: Input Path is determined by functionality */
|
||||
IOMUXC_SetPinMux(
|
||||
IOMUXC_GPIO_B1_10_ENET_REF_CLK, /* GPIO_B1_10 is configured as ENET_REF_CLK */
|
||||
1U); /* Software Input On Field: Force input path of pad GPIO_B1_10 */
|
||||
IOMUXC_SetPinMux(
|
||||
IOMUXC_GPIO_B1_11_ENET_RX_ER, /* GPIO_B1_11 is configured as ENET_RX_ER */
|
||||
0U); /* Software Input On Field: Input Path is determined by functionality */
|
||||
IOMUXC_SetPinMux(
|
||||
IOMUXC_GPIO_EMC_40_ENET_MDC, /* GPIO_EMC_40 is configured as ENET_MDC */
|
||||
0U); /* Software Input On Field: Input Path is determined by functionality */
|
||||
IOMUXC_SetPinMux(
|
||||
IOMUXC_GPIO_EMC_41_ENET_MDIO, /* GPIO_EMC_41 is configured as ENET_MDIO */
|
||||
0U); /* Software Input On Field: Input Path is determined by functionality */
|
||||
// IOMUXC_SetPinConfig(
|
||||
// IOMUXC_GPIO_AD_B0_09_GPIO1_IO09, /* GPIO_AD_B0_09 PAD functional properties : */
|
||||
// 0xB0A9u); /* Slew Rate Field: Fast Slew Rate
|
||||
// Drive Strength Field: R0/5
|
||||
// Speed Field: medium(100MHz)
|
||||
// Open Drain Enable Field: Open Drain Disabled
|
||||
// Pull / Keep Enable Field: Pull/Keeper Enabled
|
||||
// Pull / Keep Select Field: Pull
|
||||
// Pull Up / Down Config. Field: 100K Ohm Pull Up
|
||||
// Hyst. Enable Field: Hysteresis Disabled */
|
||||
|
||||
IOMUXC_SetPinConfig(
|
||||
IOMUXC_GPIO_AD_B0_03_GPIO1_IO03, /* GPIO_AD_B0_09 PAD functional properties : */
|
||||
0xB0A9u); /* Slew Rate Field: Fast Slew Rate
|
||||
Drive Strength Field: R0/5
|
||||
Speed Field: medium(100MHz)
|
||||
Open Drain Enable Field: Open Drain Disabled
|
||||
Pull / Keep Enable Field: Pull/Keeper Enabled
|
||||
Pull / Keep Select Field: Pull
|
||||
Pull Up / Down Config. Field: 100K Ohm Pull Up
|
||||
Hyst. Enable Field: Hysteresis Disabled */
|
||||
|
||||
IOMUXC_SetPinConfig(
|
||||
IOMUXC_GPIO_AD_B0_10_GPIO1_IO10, /* GPIO_AD_B0_10 PAD functional properties : */
|
||||
0xB0A9u); /* Slew Rate Field: Fast Slew Rate
|
||||
Drive Strength Field: R0/5
|
||||
Speed Field: medium(100MHz)
|
||||
Open Drain Enable Field: Open Drain Disabled
|
||||
Pull / Keep Enable Field: Pull/Keeper Enabled
|
||||
Pull / Keep Select Field: Pull
|
||||
Pull Up / Down Config. Field: 100K Ohm Pull Up
|
||||
Hyst. Enable Field: Hysteresis Disabled */
|
||||
|
||||
#if UART_DEBUG
|
||||
IOMUXC_SetPinConfig(
|
||||
IOMUXC_GPIO_AD_B0_12_LPUART1_TX, /* GPIO_AD_B0_12 PAD functional properties : */
|
||||
0x10B0u); /* Slew Rate Field: Slow Slew Rate
|
||||
Drive Strength Field: R0/6
|
||||
Speed Field: medium(100MHz)
|
||||
Open Drain Enable Field: Open Drain Disabled
|
||||
Pull / Keep Enable Field: Pull/Keeper Enabled
|
||||
Pull / Keep Select Field: Keeper
|
||||
Pull Up / Down Config. Field: 100K Ohm Pull Down
|
||||
Hyst. Enable Field: Hysteresis Disabled */
|
||||
IOMUXC_SetPinConfig(
|
||||
IOMUXC_GPIO_AD_B0_13_LPUART1_RX, /* GPIO_AD_B0_13 PAD functional properties : */
|
||||
0x10B0u); /* Slew Rate Field: Slow Slew Rate
|
||||
Drive Strength Field: R0/6
|
||||
Speed Field: medium(100MHz)
|
||||
Open Drain Enable Field: Open Drain Disabled
|
||||
Pull / Keep Enable Field: Pull/Keeper Enabled
|
||||
Pull / Keep Select Field: Keeper
|
||||
Pull Up / Down Config. Field: 100K Ohm Pull Down
|
||||
Hyst. Enable Field: Hysteresis Disabled */
|
||||
|
||||
#endif
|
||||
|
||||
IOMUXC_SetPinConfig(
|
||||
IOMUXC_GPIO_B1_04_ENET_RX_DATA00, /* GPIO_B1_04 PAD functional properties : */
|
||||
0xB0E9u); /* Slew Rate Field: Fast Slew Rate
|
||||
Drive Strength Field: R0/5
|
||||
Speed Field: max(200MHz)
|
||||
Open Drain Enable Field: Open Drain Disabled
|
||||
Pull / Keep Enable Field: Pull/Keeper Enabled
|
||||
Pull / Keep Select Field: Pull
|
||||
Pull Up / Down Config. Field: 100K Ohm Pull Up
|
||||
Hyst. Enable Field: Hysteresis Disabled */
|
||||
IOMUXC_SetPinConfig(
|
||||
IOMUXC_GPIO_B1_05_ENET_RX_DATA01, /* GPIO_B1_05 PAD functional properties : */
|
||||
0xB0E9u); /* Slew Rate Field: Fast Slew Rate
|
||||
Drive Strength Field: R0/5
|
||||
Speed Field: max(200MHz)
|
||||
Open Drain Enable Field: Open Drain Disabled
|
||||
Pull / Keep Enable Field: Pull/Keeper Enabled
|
||||
Pull / Keep Select Field: Pull
|
||||
Pull Up / Down Config. Field: 100K Ohm Pull Up
|
||||
Hyst. Enable Field: Hysteresis Disabled */
|
||||
IOMUXC_SetPinConfig(
|
||||
IOMUXC_GPIO_B1_06_ENET_RX_EN, /* GPIO_B1_06 PAD functional properties : */
|
||||
0xB0E9u); /* Slew Rate Field: Fast Slew Rate
|
||||
Drive Strength Field: R0/5
|
||||
Speed Field: max(200MHz)
|
||||
Open Drain Enable Field: Open Drain Disabled
|
||||
Pull / Keep Enable Field: Pull/Keeper Enabled
|
||||
Pull / Keep Select Field: Pull
|
||||
Pull Up / Down Config. Field: 100K Ohm Pull Up
|
||||
Hyst. Enable Field: Hysteresis Disabled */
|
||||
IOMUXC_SetPinConfig(
|
||||
IOMUXC_GPIO_B1_07_ENET_TX_DATA00, /* GPIO_B1_07 PAD functional properties : */
|
||||
0xB0E9u); /* Slew Rate Field: Fast Slew Rate
|
||||
Drive Strength Field: R0/5
|
||||
Speed Field: max(200MHz)
|
||||
Open Drain Enable Field: Open Drain Disabled
|
||||
Pull / Keep Enable Field: Pull/Keeper Enabled
|
||||
Pull / Keep Select Field: Pull
|
||||
Pull Up / Down Config. Field: 100K Ohm Pull Up
|
||||
Hyst. Enable Field: Hysteresis Disabled */
|
||||
IOMUXC_SetPinConfig(
|
||||
IOMUXC_GPIO_B1_08_ENET_TX_DATA01, /* GPIO_B1_08 PAD functional properties : */
|
||||
0xB0E9u); /* Slew Rate Field: Fast Slew Rate
|
||||
Drive Strength Field: R0/5
|
||||
Speed Field: max(200MHz)
|
||||
Open Drain Enable Field: Open Drain Disabled
|
||||
Pull / Keep Enable Field: Pull/Keeper Enabled
|
||||
Pull / Keep Select Field: Pull
|
||||
Pull Up / Down Config. Field: 100K Ohm Pull Up
|
||||
Hyst. Enable Field: Hysteresis Disabled */
|
||||
IOMUXC_SetPinConfig(
|
||||
IOMUXC_GPIO_B1_09_ENET_TX_EN, /* GPIO_B1_09 PAD functional properties : */
|
||||
0xB0E9u); /* Slew Rate Field: Fast Slew Rate
|
||||
Drive Strength Field: R0/5
|
||||
Speed Field: max(200MHz)
|
||||
Open Drain Enable Field: Open Drain Disabled
|
||||
Pull / Keep Enable Field: Pull/Keeper Enabled
|
||||
Pull / Keep Select Field: Pull
|
||||
Pull Up / Down Config. Field: 100K Ohm Pull Up
|
||||
Hyst. Enable Field: Hysteresis Disabled */
|
||||
IOMUXC_SetPinConfig(
|
||||
IOMUXC_GPIO_B1_10_ENET_REF_CLK, /* GPIO_B1_10 PAD functional properties : */
|
||||
0x31u); /* Slew Rate Field: Fast Slew Rate
|
||||
Drive Strength Field: R0/6
|
||||
Speed Field: low(50MHz)
|
||||
Open Drain Enable Field: Open Drain Disabled
|
||||
Pull / Keep Enable Field: Pull/Keeper Disabled
|
||||
Pull / Keep Select Field: Keeper
|
||||
Pull Up / Down Config. Field: 100K Ohm Pull Down
|
||||
Hyst. Enable Field: Hysteresis Disabled */
|
||||
IOMUXC_SetPinConfig(
|
||||
IOMUXC_GPIO_B1_11_ENET_RX_ER, /* GPIO_B1_11 PAD functional properties : */
|
||||
0xB0E9u); /* Slew Rate Field: Fast Slew Rate
|
||||
Drive Strength Field: R0/5
|
||||
Speed Field: max(200MHz)
|
||||
Open Drain Enable Field: Open Drain Disabled
|
||||
Pull / Keep Enable Field: Pull/Keeper Enabled
|
||||
Pull / Keep Select Field: Pull
|
||||
Pull Up / Down Config. Field: 100K Ohm Pull Up
|
||||
Hyst. Enable Field: Hysteresis Disabled */
|
||||
IOMUXC_SetPinConfig(
|
||||
IOMUXC_GPIO_EMC_40_ENET_MDC, /* GPIO_EMC_40 PAD functional properties : */
|
||||
0xB0E9u); /* Slew Rate Field: Fast Slew Rate
|
||||
Drive Strength Field: R0/5
|
||||
Speed Field: max(200MHz)
|
||||
Open Drain Enable Field: Open Drain Disabled
|
||||
Pull / Keep Enable Field: Pull/Keeper Enabled
|
||||
Pull / Keep Select Field: Pull
|
||||
Pull Up / Down Config. Field: 100K Ohm Pull Up
|
||||
Hyst. Enable Field: Hysteresis Disabled */
|
||||
IOMUXC_SetPinConfig(
|
||||
IOMUXC_GPIO_EMC_41_ENET_MDIO, /* GPIO_EMC_41 PAD functional properties : */
|
||||
0xB829u); /* Slew Rate Field: Fast Slew Rate
|
||||
Drive Strength Field: R0/5
|
||||
Speed Field: low(50MHz)
|
||||
Open Drain Enable Field: Open Drain Enabled
|
||||
Pull / Keep Enable Field: Pull/Keeper Enabled
|
||||
Pull / Keep Select Field: Pull
|
||||
Pull Up / Down Config. Field: 100K Ohm Pull Up
|
||||
Hyst. Enable Field: Hysteresis Disabled */
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************
|
||||
|
||||
@@ -5,3 +5,8 @@ select RESOURCES_SERIAL
|
||||
if BSP_USING_LPUART
|
||||
source "$BSP_DIR/third_party_driver/uart/Kconfig"
|
||||
endif
|
||||
|
||||
menuconfig BSP_USING_LWIP
|
||||
bool "Using LwIP device"
|
||||
default n
|
||||
select RESOURCES_LWIP
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
|
||||
SRC_FILES := fsl_clock.c fsl_common.c fsl_lpuart.c
|
||||
SRC_FILES := fsl_cache.c fsl_clock.c fsl_common.c fsl_lpuart.c fsl_enet.c fsl_gpio.c fsl_phy.c
|
||||
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
||||
|
||||
+623
@@ -0,0 +1,623 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Freescale Semiconductor, Inc.
|
||||
* Copyright 2016-2017 NXP
|
||||
* All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2021 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file fsl_cache.c
|
||||
* @brief cache drivers
|
||||
* @version 1.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2021.11.11
|
||||
*/
|
||||
|
||||
#include "fsl_cache.h"
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
|
||||
/* Component ID definition, used by tools. */
|
||||
#ifndef FSL_COMPONENT_ID
|
||||
#define FSL_COMPONENT_ID "platform.drivers.cache_armv7_m7"
|
||||
#endif
|
||||
|
||||
#if defined(FSL_FEATURE_SOC_L2CACHEC_COUNT) && FSL_FEATURE_SOC_L2CACHEC_COUNT
|
||||
#define L2CACHE_OPERATION_TIMEOUT 0xFFFFFU
|
||||
#define L2CACHE_8WAYS_MASK 0xFFU
|
||||
#define L2CACHE_16WAYS_MASK 0xFFFFU
|
||||
#define L2CACHE_SMALLWAYS_NUM 8U
|
||||
#define L2CACHE_1KBCOVERTOB 1024U
|
||||
#define L2CACHE_SAMLLWAYS_SIZE 16U
|
||||
#define L2CACHE_LOCKDOWN_REGNUM 8 /*!< Lock down register numbers.*/
|
||||
/*******************************************************************************
|
||||
* Prototypes
|
||||
******************************************************************************/
|
||||
/*!
|
||||
* @brief Set for all ways and waiting for the operation finished.
|
||||
* This is provided for all the background operations.
|
||||
*
|
||||
* @param auxCtlReg The auxiliary control register.
|
||||
* @param regAddr The register address to be operated.
|
||||
*/
|
||||
static void L2CACHE_SetAndWaitBackGroundOperate(uint32_t auxCtlReg, uint32_t regAddr);
|
||||
|
||||
/*!
|
||||
* @brief Invalidates the Level 2 cache line by physical address.
|
||||
* This function invalidates a cache line by physcial address.
|
||||
*
|
||||
* @param address The physical addderss of the cache.
|
||||
* The format of the address shall be :
|
||||
* bit 31 ~ bit n+1 | bitn ~ bit5 | bit4 ~ bit0
|
||||
* Tag | index | 0
|
||||
* Note: the physical address shall be aligned to the line size - 32B (256 bit).
|
||||
* so keep the last 5 bits (bit 4 ~ bit 0) of the physical address always be zero.
|
||||
* If the input address is not aligned, it will be changed to 32-byte aligned address.
|
||||
* The n is varies according to the index width.
|
||||
* @return The actual 32-byte aligned physical address be operated.
|
||||
*/
|
||||
static uint32_t L2CACHE_InvalidateLineByAddr(uint32_t address);
|
||||
|
||||
/*!
|
||||
* @brief Cleans the Level 2 cache line based on the physical address.
|
||||
* This function cleans a cache line based on a physcial address.
|
||||
*
|
||||
* @param address The physical addderss of the cache.
|
||||
* The format of the address shall be :
|
||||
* bit 31 ~ bit n+1 | bitn ~ bit5 | bit4 ~ bit0
|
||||
* Tag | index | 0
|
||||
* Note: the physical address shall be aligned to the line size - 32B (256 bit).
|
||||
* so keep the last 5 bits (bit 4 ~ bit 0) of the physical address always be zero.
|
||||
* If the input address is not aligned, it will be changed to 32-byte aligned address.
|
||||
* The n is varies according to the index width.
|
||||
* @return The actual 32-byte aligned physical address be operated.
|
||||
*/
|
||||
static uint32_t L2CACHE_CleanLineByAddr(uint32_t address);
|
||||
|
||||
/*!
|
||||
* @brief Cleans and invalidates the Level 2 cache line based on the physical address.
|
||||
* This function cleans and invalidates a cache line based on a physcial address.
|
||||
*
|
||||
* @param address The physical addderss of the cache.
|
||||
* The format of the address shall be :
|
||||
* bit 31 ~ bit n+1 | bitn ~ bit5 | bit4 ~ bit0
|
||||
* Tag | index | 0
|
||||
* Note: the physical address shall be aligned to the line size - 32B (256 bit).
|
||||
* so keep the last 5 bits (bit 4 ~ bit 0) of the physical address always be zero.
|
||||
* If the input address is not aligned, it will be changed to 32-byte aligned address.
|
||||
* The n is varies according to the index width.
|
||||
* @return The actual 32-byte aligned physical address be operated.
|
||||
*/
|
||||
static uint32_t L2CACHE_CleanInvalidateLineByAddr(uint32_t address);
|
||||
|
||||
/*!
|
||||
* @brief Gets the number of the Level 2 cache and the way size.
|
||||
* This function cleans and invalidates a cache line based on a physcial address.
|
||||
*
|
||||
* @param num_ways The number of the cache way.
|
||||
* @param size_way The way size.
|
||||
*/
|
||||
static void L2CACHE_GetWayNumSize(uint32_t *num_ways, uint32_t *size_way);
|
||||
/*******************************************************************************
|
||||
* Code
|
||||
******************************************************************************/
|
||||
static void L2CACHE_SetAndWaitBackGroundOperate(uint32_t auxCtlReg, uint32_t regAddr)
|
||||
{
|
||||
uint16_t mask = L2CACHE_8WAYS_MASK;
|
||||
uint32_t timeout = L2CACHE_OPERATION_TIMEOUT;
|
||||
|
||||
/* Check the ways used at first. */
|
||||
if (auxCtlReg & L2CACHEC_REG1_AUX_CONTROL_ASSOCIATIVITY_MASK)
|
||||
{
|
||||
mask = L2CACHE_16WAYS_MASK;
|
||||
}
|
||||
|
||||
/* Set the opeartion for all ways/entries of the cache. */
|
||||
*(uint32_t *)regAddr = mask;
|
||||
/* Waiting for until the operation is complete. */
|
||||
while ((*(volatile uint32_t *)regAddr & mask) && timeout)
|
||||
{
|
||||
__ASM("nop");
|
||||
timeout--;
|
||||
}
|
||||
}
|
||||
|
||||
static uint32_t L2CACHE_InvalidateLineByAddr(uint32_t address)
|
||||
{
|
||||
/* Align the address first. */
|
||||
address &= ~(uint32_t)(FSL_FEATURE_L2CACHE_LINESIZE_BYTE - 1);
|
||||
/* Invalidate the cache line by physical address. */
|
||||
L2CACHEC->REG7_INV_PA = address;
|
||||
|
||||
return address;
|
||||
}
|
||||
|
||||
static uint32_t L2CACHE_CleanLineByAddr(uint32_t address)
|
||||
{
|
||||
/* Align the address first. */
|
||||
address &= ~(uint32_t)(FSL_FEATURE_L2CACHE_LINESIZE_BYTE - 1);
|
||||
/* Invalidate the cache line by physical address. */
|
||||
L2CACHEC->REG7_CLEAN_PA = address;
|
||||
|
||||
return address;
|
||||
}
|
||||
|
||||
static uint32_t L2CACHE_CleanInvalidateLineByAddr(uint32_t address)
|
||||
{
|
||||
/* Align the address first. */
|
||||
address &= ~(uint32_t)(FSL_FEATURE_L2CACHE_LINESIZE_BYTE - 1);
|
||||
/* Clean and invalidate the cache line by physical address. */
|
||||
L2CACHEC->REG7_CLEAN_INV_PA = address;
|
||||
|
||||
return address;
|
||||
}
|
||||
|
||||
static void L2CACHE_GetWayNumSize(uint32_t *num_ways, uint32_t *size_way)
|
||||
{
|
||||
assert(num_ways);
|
||||
assert(size_way);
|
||||
|
||||
uint32_t number = (L2CACHEC->REG1_AUX_CONTROL & L2CACHEC_REG1_AUX_CONTROL_ASSOCIATIVITY_MASK) >>
|
||||
L2CACHEC_REG1_AUX_CONTROL_ASSOCIATIVITY_SHIFT;
|
||||
uint32_t size = (L2CACHEC->REG1_AUX_CONTROL & L2CACHEC_REG1_AUX_CONTROL_WAYSIZE_MASK) >>
|
||||
L2CACHEC_REG1_AUX_CONTROL_WAYSIZE_SHIFT;
|
||||
|
||||
*num_ways = (number + 1) * L2CACHE_SMALLWAYS_NUM;
|
||||
if (!size)
|
||||
{
|
||||
/* 0 internally mapped to the same size as 1 - 16KB.*/
|
||||
size += 1;
|
||||
}
|
||||
*size_way = (1 << (size - 1)) * L2CACHE_SAMLLWAYS_SIZE * L2CACHE_1KBCOVERTOB;
|
||||
}
|
||||
|
||||
/*!
|
||||
* brief Initializes the level 2 cache controller module.
|
||||
*
|
||||
* param config Pointer to configuration structure. See "l2cache_config_t".
|
||||
*/
|
||||
void L2CACHE_Init(l2cache_config_t *config)
|
||||
{
|
||||
assert(config);
|
||||
|
||||
uint16_t waysNum = 0xFFU; /* Default use the 8-way mask. */
|
||||
uint8_t count;
|
||||
uint32_t auxReg = 0;
|
||||
|
||||
/*The aux register must be configured when the cachec is disabled
|
||||
* So disable first if the cache controller is enabled.
|
||||
*/
|
||||
if (L2CACHEC->REG1_CONTROL & L2CACHEC_REG1_CONTROL_CE_MASK)
|
||||
{
|
||||
L2CACHE_Disable();
|
||||
}
|
||||
|
||||
/* Unlock all entries. */
|
||||
if (L2CACHEC->REG1_AUX_CONTROL & L2CACHEC_REG1_AUX_CONTROL_ASSOCIATIVITY_MASK)
|
||||
{
|
||||
waysNum = 0xFFFFU;
|
||||
}
|
||||
|
||||
for (count = 0; count < L2CACHE_LOCKDOWN_REGNUM; count++)
|
||||
{
|
||||
L2CACHE_LockdownByWayEnable(count, waysNum, false);
|
||||
}
|
||||
|
||||
/* Set the ways and way-size etc. */
|
||||
auxReg = L2CACHEC_REG1_AUX_CONTROL_ASSOCIATIVITY(config->wayNum) |
|
||||
L2CACHEC_REG1_AUX_CONTROL_WAYSIZE(config->waySize) | L2CACHEC_REG1_AUX_CONTROL_CRP(config->repacePolicy) |
|
||||
L2CACHEC_REG1_AUX_CONTROL_IPE(config->istrPrefetchEnable) |
|
||||
L2CACHEC_REG1_AUX_CONTROL_DPE(config->dataPrefetchEnable) |
|
||||
L2CACHEC_REG1_AUX_CONTROL_NLE(config->nsLockdownEnable) |
|
||||
L2CACHEC_REG1_AUX_CONTROL_FWA(config->writeAlloc) | L2CACHEC_REG1_AUX_CONTROL_HPSDRE(config->writeAlloc);
|
||||
L2CACHEC->REG1_AUX_CONTROL = auxReg;
|
||||
|
||||
/* Set the tag/data ram latency. */
|
||||
if (config->lateConfig)
|
||||
{
|
||||
uint32_t data = 0;
|
||||
/* Tag latency. */
|
||||
data = L2CACHEC_REG1_TAG_RAM_CONTROL_SL(config->lateConfig->tagSetupLate) |
|
||||
L2CACHEC_REG1_TAG_RAM_CONTROL_SL(config->lateConfig->tagSetupLate) |
|
||||
L2CACHEC_REG1_TAG_RAM_CONTROL_RAL(config->lateConfig->tagReadLate) |
|
||||
L2CACHEC_REG1_TAG_RAM_CONTROL_WAL(config->lateConfig->dataWriteLate);
|
||||
L2CACHEC->REG1_TAG_RAM_CONTROL = data;
|
||||
/* Data latency. */
|
||||
data = L2CACHEC_REG1_DATA_RAM_CONTROL_SL(config->lateConfig->dataSetupLate) |
|
||||
L2CACHEC_REG1_DATA_RAM_CONTROL_SL(config->lateConfig->dataSetupLate) |
|
||||
L2CACHEC_REG1_DATA_RAM_CONTROL_RAL(config->lateConfig->dataReadLate) |
|
||||
L2CACHEC_REG1_DATA_RAM_CONTROL_WAL(config->lateConfig->dataWriteLate);
|
||||
L2CACHEC->REG1_DATA_RAM_CONTROL = data;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* brief Gets an available default settings for the cache controller.
|
||||
*
|
||||
* This function initializes the cache controller configuration structure with default settings.
|
||||
* The default values are:
|
||||
* code
|
||||
* config->waysNum = kL2CACHE_8ways;
|
||||
* config->waySize = kL2CACHE_32KbSize;
|
||||
* config->repacePolicy = kL2CACHE_Roundrobin;
|
||||
* config->lateConfig = NULL;
|
||||
* config->istrPrefetchEnable = false;
|
||||
* config->dataPrefetchEnable = false;
|
||||
* config->nsLockdownEnable = false;
|
||||
* config->writeAlloc = kL2CACHE_UseAwcache;
|
||||
* endcode
|
||||
* param config Pointer to the configuration structure.
|
||||
*/
|
||||
void L2CACHE_GetDefaultConfig(l2cache_config_t *config)
|
||||
{
|
||||
assert(config);
|
||||
|
||||
/* Initializes the configure structure to zero. */
|
||||
memset(config, 0, sizeof(*config));
|
||||
|
||||
uint32_t number = (L2CACHEC->REG1_AUX_CONTROL & L2CACHEC_REG1_AUX_CONTROL_ASSOCIATIVITY_MASK) >>
|
||||
L2CACHEC_REG1_AUX_CONTROL_ASSOCIATIVITY_SHIFT;
|
||||
uint32_t size = (L2CACHEC->REG1_AUX_CONTROL & L2CACHEC_REG1_AUX_CONTROL_WAYSIZE_MASK) >>
|
||||
L2CACHEC_REG1_AUX_CONTROL_WAYSIZE_SHIFT;
|
||||
|
||||
/* Get the default value */
|
||||
config->wayNum = (l2cache_way_num_t)number;
|
||||
config->waySize = (l2cache_way_size)size;
|
||||
config->repacePolicy = kL2CACHE_Roundrobin;
|
||||
config->lateConfig = NULL;
|
||||
config->istrPrefetchEnable = false;
|
||||
config->dataPrefetchEnable = false;
|
||||
config->nsLockdownEnable = false;
|
||||
config->writeAlloc = kL2CACHE_UseAwcache;
|
||||
}
|
||||
|
||||
/*!
|
||||
* brief Enables the level 2 cache controller.
|
||||
* This function enables the cache controller. Must be written using a secure access.
|
||||
* If write with a Non-secure access will cause a DECERR response.
|
||||
*
|
||||
*/
|
||||
void L2CACHE_Enable(void)
|
||||
{
|
||||
/* Invalidate first. */
|
||||
L2CACHE_Invalidate();
|
||||
/* Enable the level 2 cache controller. */
|
||||
L2CACHEC->REG1_CONTROL = L2CACHEC_REG1_CONTROL_CE_MASK;
|
||||
}
|
||||
|
||||
/*!
|
||||
* brief Disables the level 2 cache controller.
|
||||
* This function disables the cache controller. Must be written using a secure access.
|
||||
* If write with a Non-secure access will cause a DECERR response.
|
||||
*
|
||||
*/
|
||||
void L2CACHE_Disable(void)
|
||||
{
|
||||
/* First CleanInvalidate all enties in the cache. */
|
||||
L2CACHE_CleanInvalidate();
|
||||
/* Disable the level 2 cache controller. */
|
||||
L2CACHEC->REG1_CONTROL &= ~L2CACHEC_REG1_CONTROL_CE_MASK;
|
||||
/* DSB - data sync barrier.*/
|
||||
__DSB();
|
||||
}
|
||||
|
||||
/*!
|
||||
* brief Invalidates the Level 2 cache.
|
||||
* This function invalidates all entries in cache.
|
||||
*
|
||||
*/
|
||||
void L2CACHE_Invalidate(void)
|
||||
{
|
||||
/* Invalidate all entries in cache. */
|
||||
L2CACHE_SetAndWaitBackGroundOperate(L2CACHEC->REG1_AUX_CONTROL, (uint32_t)&L2CACHEC->REG7_INV_WAY);
|
||||
/* Cache sync. */
|
||||
L2CACHEC->REG7_CACHE_SYNC = 0;
|
||||
}
|
||||
|
||||
/*!
|
||||
* brief Cleans the level 2 cache controller.
|
||||
* This function cleans all entries in the level 2 cache controller.
|
||||
*
|
||||
*/
|
||||
void L2CACHE_Clean(void)
|
||||
{
|
||||
/* Clean all entries of the cache. */
|
||||
L2CACHE_SetAndWaitBackGroundOperate(L2CACHEC->REG1_AUX_CONTROL, (uint32_t)&L2CACHEC->REG7_CLEAN_WAY);
|
||||
/* Cache sync. */
|
||||
L2CACHEC->REG7_CACHE_SYNC = 0;
|
||||
}
|
||||
|
||||
/*!
|
||||
* brief Cleans and invalidates the level 2 cache controller.
|
||||
* This function cleans and invalidates all entries in the level 2 cache controller.
|
||||
*
|
||||
*/
|
||||
void L2CACHE_CleanInvalidate(void)
|
||||
{
|
||||
/* Clean all entries of the cache. */
|
||||
L2CACHE_SetAndWaitBackGroundOperate(L2CACHEC->REG1_AUX_CONTROL, (uint32_t)&L2CACHEC->REG7_CLEAN_INV_WAY);
|
||||
/* Cache sync. */
|
||||
L2CACHEC->REG7_CACHE_SYNC = 0;
|
||||
}
|
||||
|
||||
/*!
|
||||
* brief Invalidates the Level 2 cache lines in the range of two physical addresses.
|
||||
* This function invalidates all cache lines between two physical addresses.
|
||||
*
|
||||
* param address The start address of the memory to be invalidated.
|
||||
* param size_byte The memory size.
|
||||
* note The start address and size_byte should be 32-byte(FSL_FEATURE_L2CACHE_LINESIZE_BYTE) aligned.
|
||||
* The startAddr here will be forced to align to L2 line size if startAddr
|
||||
* is not aligned. For the size_byte, application should make sure the
|
||||
* alignment or make sure the right operation order if the size_byte is not aligned.
|
||||
*/
|
||||
void L2CACHE_InvalidateByRange(uint32_t address, uint32_t size_byte)
|
||||
{
|
||||
uint32_t endAddr = address + size_byte;
|
||||
|
||||
/* Invalidate addresses in the range. */
|
||||
while (address < endAddr)
|
||||
{
|
||||
address = L2CACHE_InvalidateLineByAddr(address);
|
||||
/* Update the size. */
|
||||
address += FSL_FEATURE_L2CACHE_LINESIZE_BYTE;
|
||||
}
|
||||
|
||||
/* Cache sync. */
|
||||
L2CACHEC->REG7_CACHE_SYNC = 0;
|
||||
}
|
||||
|
||||
/*!
|
||||
* brief Cleans the Level 2 cache lines in the range of two physical addresses.
|
||||
* This function cleans all cache lines between two physical addresses.
|
||||
*
|
||||
* param address The start address of the memory to be cleaned.
|
||||
* param size_byte The memory size.
|
||||
* note The start address and size_byte should be 32-byte(FSL_FEATURE_L2CACHE_LINESIZE_BYTE) aligned.
|
||||
* The startAddr here will be forced to align to L2 line size if startAddr
|
||||
* is not aligned. For the size_byte, application should make sure the
|
||||
* alignment or make sure the right operation order if the size_byte is not aligned.
|
||||
*/
|
||||
void L2CACHE_CleanByRange(uint32_t address, uint32_t size_byte)
|
||||
{
|
||||
uint32_t num_ways = 0;
|
||||
uint32_t size_way = 0;
|
||||
uint32_t endAddr = address + size_byte;
|
||||
|
||||
/* Get the number and size of the cache way. */
|
||||
L2CACHE_GetWayNumSize(&num_ways, &size_way);
|
||||
|
||||
/* Check if the clean size is over the cache size. */
|
||||
if ((endAddr - address) > num_ways * size_way)
|
||||
{
|
||||
L2CACHE_Clean();
|
||||
return;
|
||||
}
|
||||
|
||||
/* Clean addresses in the range. */
|
||||
while ((address & ~(uint32_t)(FSL_FEATURE_L2CACHE_LINESIZE_BYTE - 1)) < endAddr)
|
||||
{
|
||||
/* Clean the address in the range. */
|
||||
address = L2CACHE_CleanLineByAddr(address);
|
||||
address += FSL_FEATURE_L2CACHE_LINESIZE_BYTE;
|
||||
}
|
||||
|
||||
L2CACHEC->REG7_CACHE_SYNC = 0;
|
||||
}
|
||||
|
||||
/*!
|
||||
* brief Cleans and invalidates the Level 2 cache lines in the range of two physical addresses.
|
||||
* This function cleans and invalidates all cache lines between two physical addresses.
|
||||
*
|
||||
* param address The start address of the memory to be cleaned and invalidated.
|
||||
* param size_byte The memory size.
|
||||
* note The start address and size_byte should be 32-byte(FSL_FEATURE_L2CACHE_LINESIZE_BYTE) aligned.
|
||||
* The startAddr here will be forced to align to L2 line size if startAddr
|
||||
* is not aligned. For the size_byte, application should make sure the
|
||||
* alignment or make sure the right operation order if the size_byte is not aligned.
|
||||
*/
|
||||
void L2CACHE_CleanInvalidateByRange(uint32_t address, uint32_t size_byte)
|
||||
{
|
||||
uint32_t num_ways = 0;
|
||||
uint32_t size_way = 0;
|
||||
uint32_t endAddr = address + size_byte;
|
||||
|
||||
/* Get the number and size of the cache way. */
|
||||
L2CACHE_GetWayNumSize(&num_ways, &size_way);
|
||||
|
||||
/* Check if the clean size is over the cache size. */
|
||||
if ((endAddr - address) > num_ways * size_way)
|
||||
{
|
||||
L2CACHE_CleanInvalidate();
|
||||
return;
|
||||
}
|
||||
|
||||
/* Clean addresses in the range. */
|
||||
while ((address & ~(uint32_t)(FSL_FEATURE_L2CACHE_LINESIZE_BYTE - 1)) < endAddr)
|
||||
{
|
||||
/* Clean the address in the range. */
|
||||
address = L2CACHE_CleanInvalidateLineByAddr(address);
|
||||
address += FSL_FEATURE_L2CACHE_LINESIZE_BYTE;
|
||||
}
|
||||
|
||||
L2CACHEC->REG7_CACHE_SYNC = 0;
|
||||
}
|
||||
|
||||
/*!
|
||||
* brief Enables or disables to lock down the data and instruction by way.
|
||||
* This function locks down the cached instruction/data by way and prevent the adresses from
|
||||
* being allocated and prevent dara from being evicted out of the level 2 cache.
|
||||
* But the normal cache maintenance operations that invalidate, clean or clean
|
||||
* and validate cache contents affect the locked-down cache lines as normal.
|
||||
*
|
||||
* param masterId The master id, range from 0 ~ 7.
|
||||
* param mask The ways to be enabled or disabled to lockdown.
|
||||
* each bit in value is related to each way of the cache. for example:
|
||||
* value: bit 0 ------ way 0.
|
||||
* value: bit 1 ------ way 1.
|
||||
* --------------------------
|
||||
* value: bit 15 ------ way 15.
|
||||
* Note: please make sure the value setting is align with your supported ways.
|
||||
* param enable True enable the lockdown, false to disable the lockdown.
|
||||
*/
|
||||
void L2CACHE_LockdownByWayEnable(uint32_t masterId, uint32_t mask, bool enable)
|
||||
{
|
||||
uint8_t num_ways = (L2CACHEC->REG1_AUX_CONTROL & L2CACHEC_REG1_AUX_CONTROL_ASSOCIATIVITY_MASK) >>
|
||||
L2CACHEC_REG1_AUX_CONTROL_ASSOCIATIVITY_SHIFT;
|
||||
num_ways = (num_ways + 1) * L2CACHE_SMALLWAYS_NUM;
|
||||
|
||||
assert(mask < (1U << num_ways));
|
||||
assert(masterId < L2CACHE_LOCKDOWN_REGNUM);
|
||||
|
||||
uint32_t dataReg = L2CACHEC->LOCKDOWN[masterId].REG9_D_LOCKDOWN;
|
||||
uint32_t istrReg = L2CACHEC->LOCKDOWN[masterId].REG9_I_LOCKDOWN;
|
||||
|
||||
if (enable)
|
||||
{
|
||||
/* Data lockdown. */
|
||||
L2CACHEC->LOCKDOWN[masterId].REG9_D_LOCKDOWN = dataReg | mask;
|
||||
/* Instruction lockdown. */
|
||||
L2CACHEC->LOCKDOWN[masterId].REG9_I_LOCKDOWN = istrReg | mask;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Data lockdown. */
|
||||
L2CACHEC->LOCKDOWN[masterId].REG9_D_LOCKDOWN = dataReg & ~mask;
|
||||
/* Instruction lockdown. */
|
||||
L2CACHEC->LOCKDOWN[masterId].REG9_I_LOCKDOWN = istrReg & ~mask;
|
||||
}
|
||||
}
|
||||
#endif /* FSL_FEATURE_SOC_L2CACHEC_COUNT */
|
||||
|
||||
/*!
|
||||
* brief Invalidate cortex-m7 L1 instruction cache by range.
|
||||
*
|
||||
* param address The start address of the memory to be invalidated.
|
||||
* param size_byte The memory size.
|
||||
* note The start address and size_byte should be 32-byte(FSL_FEATURE_L1ICACHE_LINESIZE_BYTE) aligned.
|
||||
* The startAddr here will be forced to align to L1 I-cache line size if
|
||||
* startAddr is not aligned. For the size_byte, application should make sure the
|
||||
* alignment or make sure the right operation order if the size_byte is not aligned.
|
||||
*/
|
||||
void L1CACHE_InvalidateICacheByRange(uint32_t address, uint32_t size_byte)
|
||||
{
|
||||
#if (__DCACHE_PRESENT == 1U)
|
||||
uint32_t addr = address & (uint32_t) ~(FSL_FEATURE_L1ICACHE_LINESIZE_BYTE - 1);
|
||||
int32_t size = size_byte + address - addr;
|
||||
uint32_t linesize = 32U;
|
||||
|
||||
__DSB();
|
||||
while (size > 0)
|
||||
{
|
||||
SCB->ICIMVAU = addr;
|
||||
addr += linesize;
|
||||
size -= linesize;
|
||||
}
|
||||
__DSB();
|
||||
__ISB();
|
||||
#endif
|
||||
}
|
||||
|
||||
/*!
|
||||
* brief Invalidates all instruction caches by range.
|
||||
*
|
||||
* Both cortex-m7 L1 cache line and L2 PL310 cache line length is 32-byte.
|
||||
*
|
||||
* param address The physical address.
|
||||
* param size_byte size of the memory to be invalidated.
|
||||
* note address and size should be aligned to cache line size
|
||||
* 32-Byte due to the cache operation unit is one cache line. The startAddr here will be forced
|
||||
* to align to the cache line size if startAddr is not aligned. For the size_byte, application should
|
||||
* make sure the alignment or make sure the right operation order if the size_byte is not aligned.
|
||||
*/
|
||||
void ICACHE_InvalidateByRange(uint32_t address, uint32_t size_byte)
|
||||
{
|
||||
#if defined(FSL_FEATURE_SOC_L2CACHEC_COUNT) && FSL_FEATURE_SOC_L2CACHEC_COUNT
|
||||
#if defined(FSL_SDK_DISBLE_L2CACHE_PRESENT) && !FSL_SDK_DISBLE_L2CACHE_PRESENT
|
||||
L2CACHE_InvalidateByRange(address, size_byte);
|
||||
#endif /* !FSL_SDK_DISBLE_L2CACHE_PRESENT */
|
||||
#endif /* FSL_FEATURE_SOC_L2CACHEC_COUNT */
|
||||
|
||||
L1CACHE_InvalidateICacheByRange(address, size_byte);
|
||||
}
|
||||
|
||||
/*!
|
||||
* brief Invalidates all data caches by range.
|
||||
*
|
||||
* Both cortex-m7 L1 cache line and L2 PL310 cache line length is 32-byte.
|
||||
*
|
||||
* param address The physical address.
|
||||
* param size_byte size of the memory to be invalidated.
|
||||
* note address and size should be aligned to cache line size
|
||||
* 32-Byte due to the cache operation unit is one cache line. The startAddr here will be forced
|
||||
* to align to the cache line size if startAddr is not aligned. For the size_byte, application should
|
||||
* make sure the alignment or make sure the right operation order if the size_byte is not aligned.
|
||||
*/
|
||||
void DCACHE_InvalidateByRange(uint32_t address, uint32_t size_byte)
|
||||
{
|
||||
#if defined(FSL_FEATURE_SOC_L2CACHEC_COUNT) && FSL_FEATURE_SOC_L2CACHEC_COUNT
|
||||
#if defined(FSL_SDK_DISBLE_L2CACHE_PRESENT) && !FSL_SDK_DISBLE_L2CACHE_PRESENT
|
||||
L2CACHE_InvalidateByRange(address, size_byte);
|
||||
#endif /* !FSL_SDK_DISBLE_L2CACHE_PRESENT */
|
||||
#endif /* FSL_FEATURE_SOC_L2CACHEC_COUNT */
|
||||
L1CACHE_InvalidateDCacheByRange(address, size_byte);
|
||||
}
|
||||
|
||||
/*!
|
||||
* brief Cleans all data caches by range.
|
||||
*
|
||||
* Both cortex-m7 L1 cache line and L2 PL310 cache line length is 32-byte.
|
||||
*
|
||||
* param address The physical address.
|
||||
* param size_byte size of the memory to be cleaned.
|
||||
* note address and size should be aligned to cache line size
|
||||
* 32-Byte due to the cache operation unit is one cache line. The startAddr here will be forced
|
||||
* to align to the cache line size if startAddr is not aligned. For the size_byte, application should
|
||||
* make sure the alignment or make sure the right operation order if the size_byte is not aligned.
|
||||
*/
|
||||
void DCACHE_CleanByRange(uint32_t address, uint32_t size_byte)
|
||||
{
|
||||
L1CACHE_CleanDCacheByRange(address, size_byte);
|
||||
#if defined(FSL_FEATURE_SOC_L2CACHEC_COUNT) && FSL_FEATURE_SOC_L2CACHEC_COUNT
|
||||
#if defined(FSL_SDK_DISBLE_L2CACHE_PRESENT) && !FSL_SDK_DISBLE_L2CACHE_PRESENT
|
||||
L2CACHE_CleanByRange(address, size_byte);
|
||||
#endif /* !FSL_SDK_DISBLE_L2CACHE_PRESENT */
|
||||
#endif /* FSL_FEATURE_SOC_L2CACHEC_COUNT */
|
||||
}
|
||||
|
||||
/*!
|
||||
* brief Cleans and Invalidates all data caches by range.
|
||||
*
|
||||
* Both cortex-m7 L1 cache line and L2 PL310 cache line length is 32-byte.
|
||||
*
|
||||
* param address The physical address.
|
||||
* param size_byte size of the memory to be cleaned and invalidated.
|
||||
* note address and size should be aligned to cache line size
|
||||
* 32-Byte due to the cache operation unit is one cache line. The startAddr here will be forced
|
||||
* to align to the cache line size if startAddr is not aligned. For the size_byte, application should
|
||||
* make sure the alignment or make sure the right operation order if the size_byte is not aligned.
|
||||
*/
|
||||
void DCACHE_CleanInvalidateByRange(uint32_t address, uint32_t size_byte)
|
||||
{
|
||||
L1CACHE_CleanInvalidateDCacheByRange(address, size_byte);
|
||||
#if defined(FSL_FEATURE_SOC_L2CACHEC_COUNT) && FSL_FEATURE_SOC_L2CACHEC_COUNT
|
||||
#if defined(FSL_SDK_DISBLE_L2CACHE_PRESENT) && !FSL_SDK_DISBLE_L2CACHE_PRESENT
|
||||
L2CACHE_CleanInvalidateByRange(address, size_byte);
|
||||
#endif /* !FSL_SDK_DISBLE_L2CACHE_PRESENT */
|
||||
#endif /* FSL_FEATURE_SOC_L2CACHEC_COUNT */
|
||||
}
|
||||
+488
@@ -0,0 +1,488 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Freescale Semiconductor, Inc.
|
||||
* Copyright 2016-2017 NXP
|
||||
* All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2021 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file fsl_cache.h
|
||||
* @brief cache drivers
|
||||
* @version 1.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2021.11.11
|
||||
*/
|
||||
|
||||
#ifndef _FSL_CACHE_H_
|
||||
#define _FSL_CACHE_H_
|
||||
|
||||
#include "fsl_common.h"
|
||||
|
||||
/*!
|
||||
* @addtogroup cache
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
|
||||
/*! @name Driver version */
|
||||
/*@{*/
|
||||
/*! @brief cache driver version 2.0.1. */
|
||||
#define FSL_CACHE_DRIVER_VERSION (MAKE_VERSION(2, 0, 1))
|
||||
/*@}*/
|
||||
|
||||
#if defined(FSL_FEATURE_SOC_L2CACHEC_COUNT) && FSL_FEATURE_SOC_L2CACHEC_COUNT
|
||||
#ifndef FSL_SDK_DISBLE_L2CACHE_PRESENT
|
||||
#define FSL_SDK_DISBLE_L2CACHE_PRESENT 0
|
||||
#endif
|
||||
#endif /* FSL_FEATURE_SOC_L2CACHEC_COUNT */
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
#if defined(FSL_FEATURE_SOC_L2CACHEC_COUNT) && FSL_FEATURE_SOC_L2CACHEC_COUNT
|
||||
|
||||
/*! @brief Number of level 2 cache controller ways. */
|
||||
typedef enum _l2cache_way_num
|
||||
{
|
||||
kL2CACHE_8ways = 0, /*!< 8 ways. */
|
||||
#if defined(FSL_FEATURE_L2CACHE_SUPPORT_16_WAY_ASSOCIATIVITY) && FSL_FEATURE_L2CACHE_SUPPORT_16_WAY_ASSOCIATIVITY
|
||||
kL2CACHE_16ways /*!< 16 ways. */
|
||||
#endif /* FSL_FEATURE_L2CACHE_SUPPORT_16_WAY_ASSOCIATIVITY */
|
||||
} l2cache_way_num_t;
|
||||
|
||||
/*! @brief Level 2 cache controller way size. */
|
||||
typedef enum _l2cache_way_size
|
||||
{
|
||||
kL2CACHE_16KBSize = 1, /*!< 16 KB way size. */
|
||||
kL2CACHE_32KBSize = 2, /*!< 32 KB way size. */
|
||||
kL2CACHE_64KBSize = 3, /*!< 64 KB way size. */
|
||||
kL2CACHE_128KBSize = 4, /*!< 128 KB way size. */
|
||||
kL2CACHE_256KBSize = 5, /*!< 256 KB way size. */
|
||||
kL2CACHE_512KBSize = 6 /*!< 512 KB way size. */
|
||||
} l2cache_way_size;
|
||||
|
||||
/*! @brief Level 2 cache controller replacement policy. */
|
||||
typedef enum _l2cache_replacement
|
||||
{
|
||||
kL2CACHE_Pseudorandom = 0U, /*!< Peseudo-random replacement policy using an lfsr. */
|
||||
kL2CACHE_Roundrobin /*!< Round-robin replacemnt policy. */
|
||||
} l2cache_replacement_t;
|
||||
|
||||
/*! @brief Level 2 cache controller force write allocate options. */
|
||||
typedef enum _l2cache_writealloc
|
||||
{
|
||||
kL2CACHE_UseAwcache = 0, /*!< Use AWCAHE attribute for the write allocate. */
|
||||
kL2CACHE_NoWriteallocate, /*!< Force no write allocate. */
|
||||
kL2CACHE_forceWriteallocate /*!< Force write allocate when write misses. */
|
||||
} l2cache_writealloc_t;
|
||||
|
||||
/*! @brief Level 2 cache controller tag/data ram latency. */
|
||||
typedef enum _l2cache_latency
|
||||
{
|
||||
kL2CACHE_1CycleLate = 0, /*!< 1 cycle of latency. */
|
||||
kL2CACHE_2CycleLate, /*!< 2 cycle of latency. */
|
||||
kL2CACHE_3CycleLate, /*!< 3 cycle of latency. */
|
||||
kL2CACHE_4CycleLate, /*!< 4 cycle of latency. */
|
||||
kL2CACHE_5CycleLate, /*!< 5 cycle of latency. */
|
||||
kL2CACHE_6CycleLate, /*!< 6 cycle of latency. */
|
||||
kL2CACHE_7CycleLate, /*!< 7 cycle of latency. */
|
||||
kL2CACHE_8CycleLate /*!< 8 cycle of latency. */
|
||||
} l2cache_latency_t;
|
||||
|
||||
/*! @brief Level 2 cache controller tag/data ram latency configure structure. */
|
||||
typedef struct _l2cache_latency_config
|
||||
{
|
||||
l2cache_latency_t tagWriteLate; /*!< Tag write latency. */
|
||||
l2cache_latency_t tagReadLate; /*!< Tag Read latency. */
|
||||
l2cache_latency_t tagSetupLate; /*!< Tag setup latency. */
|
||||
l2cache_latency_t dataWriteLate; /*!< Data write latency. */
|
||||
l2cache_latency_t dataReadLate; /*!< Data Read latency. */
|
||||
l2cache_latency_t dataSetupLate; /*!< Data setup latency. */
|
||||
} L2cache_latency_config_t;
|
||||
|
||||
/*! @brief Level 2 cache controller configure structure. */
|
||||
typedef struct _l2cache_config
|
||||
{
|
||||
/* ------------------------ l2 cachec basic settings ---------------------------- */
|
||||
l2cache_way_num_t wayNum; /*!< The number of ways. */
|
||||
l2cache_way_size waySize; /*!< The way size = Cache Ram size / wayNum. */
|
||||
l2cache_replacement_t repacePolicy; /*!< Replacemnet policy. */
|
||||
/* ------------------------ tag/data ram latency settings ----------------------- */
|
||||
L2cache_latency_config_t *lateConfig; /*!< Tag/data latency configure. Set NUll if not required. */
|
||||
/* ------------------------ Prefetch enable settings ---------------------------- */
|
||||
bool istrPrefetchEnable; /*!< Instruction prefetch enable. */
|
||||
bool dataPrefetchEnable; /*!< Data prefetch enable. */
|
||||
/* ------------------------ Non-secure access settings -------------------------- */
|
||||
bool nsLockdownEnable; /*!< None-secure lockdown enable. */
|
||||
/* ------------------------ other settings -------------------------------------- */
|
||||
l2cache_writealloc_t writeAlloc; /*!< Write allcoate force option. */
|
||||
} l2cache_config_t;
|
||||
#endif /* FSL_FEATURE_SOC_L2CACHEC_COUNT */
|
||||
/*******************************************************************************
|
||||
* API
|
||||
******************************************************************************/
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* @name Control for cortex-m7 L1 cache
|
||||
*@{
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @brief Enables cortex-m7 L1 instruction cache.
|
||||
*
|
||||
*/
|
||||
static inline void L1CACHE_EnableICache(void)
|
||||
{
|
||||
SCB_EnableICache();
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Disables cortex-m7 L1 instruction cache.
|
||||
*
|
||||
*/
|
||||
static inline void L1CACHE_DisableICache(void)
|
||||
{
|
||||
SCB_DisableICache();
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Invalidate cortex-m7 L1 instruction cache.
|
||||
*
|
||||
*/
|
||||
static inline void L1CACHE_InvalidateICache(void)
|
||||
{
|
||||
SCB_InvalidateICache();
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Invalidate cortex-m7 L1 instruction cache by range.
|
||||
*
|
||||
* @param address The start address of the memory to be invalidated.
|
||||
* @param size_byte The memory size.
|
||||
* @note The start address and size_byte should be 32-byte(FSL_FEATURE_L1ICACHE_LINESIZE_BYTE) aligned.
|
||||
* The startAddr here will be forced to align to L1 I-cache line size if
|
||||
* startAddr is not aligned. For the size_byte, application should make sure the
|
||||
* alignment or make sure the right operation order if the size_byte is not aligned.
|
||||
*/
|
||||
void L1CACHE_InvalidateICacheByRange(uint32_t address, uint32_t size_byte);
|
||||
|
||||
/*!
|
||||
* @brief Enables cortex-m7 L1 data cache.
|
||||
*
|
||||
*/
|
||||
static inline void L1CACHE_EnableDCache(void)
|
||||
{
|
||||
SCB_EnableDCache();
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Disables cortex-m7 L1 data cache.
|
||||
*
|
||||
*/
|
||||
static inline void L1CACHE_DisableDCache(void)
|
||||
{
|
||||
SCB_DisableDCache();
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Invalidates cortex-m7 L1 data cache.
|
||||
*
|
||||
*/
|
||||
static inline void L1CACHE_InvalidateDCache(void)
|
||||
{
|
||||
SCB_InvalidateDCache();
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Cleans cortex-m7 L1 data cache.
|
||||
*
|
||||
*/
|
||||
static inline void L1CACHE_CleanDCache(void)
|
||||
{
|
||||
SCB_CleanDCache();
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Cleans and Invalidates cortex-m7 L1 data cache.
|
||||
*
|
||||
*/
|
||||
static inline void L1CACHE_CleanInvalidateDCache(void)
|
||||
{
|
||||
SCB_CleanInvalidateDCache();
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Invalidates cortex-m7 L1 data cache by range.
|
||||
*
|
||||
* @param address The start address of the memory to be invalidated.
|
||||
* @param size_byte The memory size.
|
||||
* @note The start address and size_byte should be 32-byte(FSL_FEATURE_L1DCACHE_LINESIZE_BYTE) aligned.
|
||||
* The startAddr here will be forced to align to L1 D-cache line size if
|
||||
* startAddr is not aligned. For the size_byte, application should make sure the
|
||||
* alignment or make sure the right operation order if the size_byte is not aligned.
|
||||
*/
|
||||
static inline void L1CACHE_InvalidateDCacheByRange(uint32_t address, uint32_t size_byte)
|
||||
{
|
||||
uint32_t startAddr = address & (uint32_t) ~(FSL_FEATURE_L1DCACHE_LINESIZE_BYTE - 1);
|
||||
uint32_t size = size_byte + address - startAddr;
|
||||
|
||||
SCB_InvalidateDCache_by_Addr((uint32_t *)startAddr, size);
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Cleans cortex-m7 L1 data cache by range.
|
||||
*
|
||||
* @param address The start address of the memory to be cleaned.
|
||||
* @param size_byte The memory size.
|
||||
* @note The start address and size_byte should be 32-byte(FSL_FEATURE_L1DCACHE_LINESIZE_BYTE) aligned.
|
||||
* The startAddr here will be forced to align to L1 D-cache line size if
|
||||
* startAddr is not aligned. For the size_byte, application should make sure the
|
||||
* alignment or make sure the right operation order if the size_byte is not aligned.
|
||||
*/
|
||||
static inline void L1CACHE_CleanDCacheByRange(uint32_t address, uint32_t size_byte)
|
||||
{
|
||||
uint32_t startAddr = address & (uint32_t) ~(FSL_FEATURE_L1DCACHE_LINESIZE_BYTE - 1);
|
||||
uint32_t size = size_byte + address - startAddr;
|
||||
|
||||
SCB_CleanDCache_by_Addr((uint32_t *)startAddr, size);
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Cleans and Invalidates cortex-m7 L1 data cache by range.
|
||||
*
|
||||
* @param address The start address of the memory to be clean and invalidated.
|
||||
* @param size_byte The memory size.
|
||||
* @note The start address and size_byte should be 32-byte(FSL_FEATURE_L1DCACHE_LINESIZE_BYTE) aligned.
|
||||
* The startAddr here will be forced to align to L1 D-cache line size if
|
||||
* startAddr is not aligned. For the size_byte, application should make sure the
|
||||
* alignment or make sure the right operation order if the size_byte is not aligned.
|
||||
*/
|
||||
static inline void L1CACHE_CleanInvalidateDCacheByRange(uint32_t address, uint32_t size_byte)
|
||||
{
|
||||
uint32_t startAddr = address & (uint32_t) ~(FSL_FEATURE_L1DCACHE_LINESIZE_BYTE - 1);
|
||||
uint32_t size = size_byte + address - startAddr;
|
||||
|
||||
SCB_CleanInvalidateDCache_by_Addr((uint32_t *)startAddr, size);
|
||||
}
|
||||
/*@}*/
|
||||
|
||||
#if defined(FSL_FEATURE_SOC_L2CACHEC_COUNT) && FSL_FEATURE_SOC_L2CACHEC_COUNT
|
||||
/*!
|
||||
* @name Control for L2 pl310 cache
|
||||
*@{
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @brief Initializes the level 2 cache controller module.
|
||||
*
|
||||
* @param config Pointer to configuration structure. See "l2cache_config_t".
|
||||
*/
|
||||
void L2CACHE_Init(l2cache_config_t *config);
|
||||
|
||||
/*!
|
||||
* @brief Gets an available default settings for the cache controller.
|
||||
*
|
||||
* This function initializes the cache controller configuration structure with default settings.
|
||||
* The default values are:
|
||||
* @code
|
||||
* config->waysNum = kL2CACHE_8ways;
|
||||
* config->waySize = kL2CACHE_32KbSize;
|
||||
* config->repacePolicy = kL2CACHE_Roundrobin;
|
||||
* config->lateConfig = NULL;
|
||||
* config->istrPrefetchEnable = false;
|
||||
* config->dataPrefetchEnable = false;
|
||||
* config->nsLockdownEnable = false;
|
||||
* config->writeAlloc = kL2CACHE_UseAwcache;
|
||||
* @endcode
|
||||
* @param config Pointer to the configuration structure.
|
||||
*/
|
||||
void L2CACHE_GetDefaultConfig(l2cache_config_t *config);
|
||||
|
||||
/*!
|
||||
* @brief Enables the level 2 cache controller.
|
||||
* This function enables the cache controller. Must be written using a secure access.
|
||||
* If write with a Non-secure access will cause a DECERR response.
|
||||
*
|
||||
*/
|
||||
void L2CACHE_Enable(void);
|
||||
|
||||
/*!
|
||||
* @brief Disables the level 2 cache controller.
|
||||
* This function disables the cache controller. Must be written using a secure access.
|
||||
* If write with a Non-secure access will cause a DECERR response.
|
||||
*
|
||||
*/
|
||||
void L2CACHE_Disable(void);
|
||||
|
||||
/*!
|
||||
* @brief Invalidates the Level 2 cache.
|
||||
* This function invalidates all entries in cache.
|
||||
*
|
||||
*/
|
||||
void L2CACHE_Invalidate(void);
|
||||
|
||||
/*!
|
||||
* @brief Invalidates the Level 2 cache lines in the range of two physical addresses.
|
||||
* This function invalidates all cache lines between two physical addresses.
|
||||
*
|
||||
* @param address The start address of the memory to be invalidated.
|
||||
* @param size_byte The memory size.
|
||||
* @note The start address and size_byte should be 32-byte(FSL_FEATURE_L2CACHE_LINESIZE_BYTE) aligned.
|
||||
* The startAddr here will be forced to align to L2 line size if startAddr
|
||||
* is not aligned. For the size_byte, application should make sure the
|
||||
* alignment or make sure the right operation order if the size_byte is not aligned.
|
||||
*/
|
||||
void L2CACHE_InvalidateByRange(uint32_t address, uint32_t size_byte);
|
||||
|
||||
/*!
|
||||
* @brief Cleans the level 2 cache controller.
|
||||
* This function cleans all entries in the level 2 cache controller.
|
||||
*
|
||||
*/
|
||||
void L2CACHE_Clean(void);
|
||||
|
||||
/*!
|
||||
* @brief Cleans the Level 2 cache lines in the range of two physical addresses.
|
||||
* This function cleans all cache lines between two physical addresses.
|
||||
*
|
||||
* @param address The start address of the memory to be cleaned.
|
||||
* @param size_byte The memory size.
|
||||
* @note The start address and size_byte should be 32-byte(FSL_FEATURE_L2CACHE_LINESIZE_BYTE) aligned.
|
||||
* The startAddr here will be forced to align to L2 line size if startAddr
|
||||
* is not aligned. For the size_byte, application should make sure the
|
||||
* alignment or make sure the right operation order if the size_byte is not aligned.
|
||||
*/
|
||||
void L2CACHE_CleanByRange(uint32_t address, uint32_t size_byte);
|
||||
|
||||
/*!
|
||||
* @brief Cleans and invalidates the level 2 cache controller.
|
||||
* This function cleans and invalidates all entries in the level 2 cache controller.
|
||||
*
|
||||
*/
|
||||
void L2CACHE_CleanInvalidate(void);
|
||||
|
||||
/*!
|
||||
* @brief Cleans and invalidates the Level 2 cache lines in the range of two physical addresses.
|
||||
* This function cleans and invalidates all cache lines between two physical addresses.
|
||||
*
|
||||
* @param address The start address of the memory to be cleaned and invalidated.
|
||||
* @param size_byte The memory size.
|
||||
* @note The start address and size_byte should be 32-byte(FSL_FEATURE_L2CACHE_LINESIZE_BYTE) aligned.
|
||||
* The startAddr here will be forced to align to L2 line size if startAddr
|
||||
* is not aligned. For the size_byte, application should make sure the
|
||||
* alignment or make sure the right operation order if the size_byte is not aligned.
|
||||
*/
|
||||
void L2CACHE_CleanInvalidateByRange(uint32_t address, uint32_t size_byte);
|
||||
|
||||
/*!
|
||||
* @brief Enables or disables to lock down the data and instruction by way.
|
||||
* This function locks down the cached instruction/data by way and prevent the adresses from
|
||||
* being allocated and prevent dara from being evicted out of the level 2 cache.
|
||||
* But the normal cache maintenance operations that invalidate, clean or clean
|
||||
* and validate cache contents affect the locked-down cache lines as normal.
|
||||
*
|
||||
* @param masterId The master id, range from 0 ~ 7.
|
||||
* @param mask The ways to be enabled or disabled to lockdown.
|
||||
* each bit in value is related to each way of the cache. for example:
|
||||
* value: bit 0 ------ way 0.
|
||||
* value: bit 1 ------ way 1.
|
||||
* --------------------------
|
||||
* value: bit 15 ------ way 15.
|
||||
* Note: please make sure the value setting is align with your supported ways.
|
||||
* @param enable True enable the lockdown, false to disable the lockdown.
|
||||
*/
|
||||
void L2CACHE_LockdownByWayEnable(uint32_t masterId, uint32_t mask, bool enable);
|
||||
|
||||
/*@}*/
|
||||
#endif /* FSL_FEATURE_SOC_L2CACHEC_COUNT */
|
||||
|
||||
/*!
|
||||
* @name Unified Cache Control for all caches (cortex-m7 L1 cache + l2 pl310)
|
||||
* Mainly used for many drivers for easy cache operation.
|
||||
*@{
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @brief Invalidates all instruction caches by range.
|
||||
*
|
||||
* Both cortex-m7 L1 cache line and L2 PL310 cache line length is 32-byte.
|
||||
*
|
||||
* @param address The physical address.
|
||||
* @param size_byte size of the memory to be invalidated.
|
||||
* @note address and size should be aligned to cache line size
|
||||
* 32-Byte due to the cache operation unit is one cache line. The startAddr here will be forced
|
||||
* to align to the cache line size if startAddr is not aligned. For the size_byte, application should
|
||||
* make sure the alignment or make sure the right operation order if the size_byte is not aligned.
|
||||
*/
|
||||
void ICACHE_InvalidateByRange(uint32_t address, uint32_t size_byte);
|
||||
|
||||
/*!
|
||||
* @brief Invalidates all data caches by range.
|
||||
*
|
||||
* Both cortex-m7 L1 cache line and L2 PL310 cache line length is 32-byte.
|
||||
*
|
||||
* @param address The physical address.
|
||||
* @param size_byte size of the memory to be invalidated.
|
||||
* @note address and size should be aligned to cache line size
|
||||
* 32-Byte due to the cache operation unit is one cache line. The startAddr here will be forced
|
||||
* to align to the cache line size if startAddr is not aligned. For the size_byte, application should
|
||||
* make sure the alignment or make sure the right operation order if the size_byte is not aligned.
|
||||
*/
|
||||
void DCACHE_InvalidateByRange(uint32_t address, uint32_t size_byte);
|
||||
|
||||
/*!
|
||||
* @brief Cleans all data caches by range.
|
||||
*
|
||||
* Both cortex-m7 L1 cache line and L2 PL310 cache line length is 32-byte.
|
||||
*
|
||||
* @param address The physical address.
|
||||
* @param size_byte size of the memory to be cleaned.
|
||||
* @note address and size should be aligned to cache line size
|
||||
* 32-Byte due to the cache operation unit is one cache line. The startAddr here will be forced
|
||||
* to align to the cache line size if startAddr is not aligned. For the size_byte, application should
|
||||
* make sure the alignment or make sure the right operation order if the size_byte is not aligned.
|
||||
*/
|
||||
void DCACHE_CleanByRange(uint32_t address, uint32_t size_byte);
|
||||
|
||||
/*!
|
||||
* @brief Cleans and Invalidates all data caches by range.
|
||||
*
|
||||
* Both cortex-m7 L1 cache line and L2 PL310 cache line length is 32-byte.
|
||||
*
|
||||
* @param address The physical address.
|
||||
* @param size_byte size of the memory to be cleaned and invalidated.
|
||||
* @note address and size should be aligned to cache line size
|
||||
* 32-Byte due to the cache operation unit is one cache line. The startAddr here will be forced
|
||||
* to align to the cache line size if startAddr is not aligned. For the size_byte, application should
|
||||
* make sure the alignment or make sure the right operation order if the size_byte is not aligned.
|
||||
*/
|
||||
void DCACHE_CleanInvalidateByRange(uint32_t address, uint32_t size_byte);
|
||||
|
||||
/*@}*/
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
/*! @}*/
|
||||
|
||||
#endif /* _FSL_CACHE_H_*/
|
||||
@@ -5,6 +5,26 @@
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2021 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file fsl_clock.c
|
||||
* @brief clock drivers
|
||||
* @version 1.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2021.11.11
|
||||
*/
|
||||
|
||||
#include "fsl_clock.h"
|
||||
/* Component ID definition, used by tools. */
|
||||
#ifndef FSL_COMPONENT_ID
|
||||
|
||||
+337
-228
@@ -1,10 +1,30 @@
|
||||
/*
|
||||
* Copyright 2017 NXP
|
||||
* Copyright 2017 - 2019 NXP
|
||||
* All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2021 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file fsl_clock.h
|
||||
* @brief clock drivers
|
||||
* @version 1.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2021.11.11
|
||||
*/
|
||||
|
||||
#ifndef _FSL_CLOCK_H_
|
||||
#define _FSL_CLOCK_H_
|
||||
|
||||
@@ -39,8 +59,13 @@
|
||||
|
||||
/*! @name Driver version */
|
||||
/*@{*/
|
||||
/*! @brief CLOCK driver version 2.1.5. */
|
||||
#define FSL_CLOCK_DRIVER_VERSION (MAKE_VERSION(2, 1, 5))
|
||||
/*! @brief CLOCK driver version 2.2.0. */
|
||||
#define FSL_CLOCK_DRIVER_VERSION (MAKE_VERSION(2, 2, 0))
|
||||
|
||||
/* Definition for delay API in clock driver, users can redefine it to the real application. */
|
||||
#ifndef SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY
|
||||
#define SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY (600000000UL)
|
||||
#endif
|
||||
|
||||
/* analog pll definition */
|
||||
#define CCM_ANALOG_PLL_BYPASS_SHIFT (16U)
|
||||
@@ -48,9 +73,36 @@
|
||||
#define CCM_ANALOG_PLL_BYPASS_CLK_SRC_SHIFT (14U)
|
||||
|
||||
/*@}*/
|
||||
#define CCM_TUPLE(reg, shift, mask, busyShift) \
|
||||
(int)((((uint32_t)(&((CCM_Type *)0U)->reg)) & 0xFFU) | ((shift) << 8U) | \
|
||||
((((mask) >> (shift)) & 0x1FFFU) << 13U) | ((busyShift) << 26U))
|
||||
|
||||
/*!
|
||||
* @brief CCM registers offset.
|
||||
*/
|
||||
#define CCSR_OFFSET 0x0C
|
||||
#define CBCDR_OFFSET 0x14
|
||||
#define CBCMR_OFFSET 0x18
|
||||
#define CSCMR1_OFFSET 0x1C
|
||||
#define CSCMR2_OFFSET 0x20
|
||||
#define CSCDR1_OFFSET 0x24
|
||||
#define CDCDR_OFFSET 0x30
|
||||
#define CSCDR2_OFFSET 0x38
|
||||
#define CSCDR3_OFFSET 0x3C
|
||||
#define CACRR_OFFSET 0x10
|
||||
#define CS1CDR_OFFSET 0x28
|
||||
#define CS2CDR_OFFSET 0x2C
|
||||
|
||||
/*!
|
||||
* @brief CCM Analog registers offset.
|
||||
*/
|
||||
#define PLL_ARM_OFFSET 0x00
|
||||
#define PLL_SYS_OFFSET 0x30
|
||||
#define PLL_USB1_OFFSET 0x10
|
||||
#define PLL_AUDIO_OFFSET 0x70
|
||||
#define PLL_VIDEO_OFFSET 0xA0
|
||||
#define PLL_ENET_OFFSET 0xE0
|
||||
#define PLL_USB2_OFFSET 0x20
|
||||
|
||||
#define CCM_TUPLE(reg, shift, mask, busyShift) \
|
||||
(int)((reg & 0xFFU) | ((shift) << 8U) | ((((mask) >> (shift)) & 0x1FFFU) << 13U) | ((busyShift) << 26U))
|
||||
#define CCM_TUPLE_REG(base, tuple) (*((volatile uint32_t *)(((uint32_t)(base)) + ((tuple)&0xFFU))))
|
||||
#define CCM_TUPLE_SHIFT(tuple) (((tuple) >> 8U) & 0x1FU)
|
||||
#define CCM_TUPLE_MASK(tuple) ((uint32_t)((((tuple) >> 13U) & 0x1FFFU) << ((((tuple) >> 8U) & 0x1FU))))
|
||||
@@ -61,7 +113,7 @@
|
||||
/*!
|
||||
* @brief CCM ANALOG tuple macros to map corresponding registers and bit fields.
|
||||
*/
|
||||
#define CCM_ANALOG_TUPLE(reg, shift) ((((uint32_t)(&((CCM_ANALOG_Type *)0U)->reg) & 0xFFFU) << 16U) | (shift))
|
||||
#define CCM_ANALOG_TUPLE(reg, shift) (((reg & 0xFFFU) << 16U) | (shift))
|
||||
#define CCM_ANALOG_TUPLE_SHIFT(tuple) (((uint32_t)tuple) & 0x1FU)
|
||||
#define CCM_ANALOG_TUPLE_REG_OFF(base, tuple, off) \
|
||||
(*((volatile uint32_t *)((uint32_t)base + (((uint32_t)tuple >> 16U) & 0xFFFU) + off)))
|
||||
@@ -271,16 +323,15 @@ extern volatile uint32_t g_rtcXtalFreq;
|
||||
}
|
||||
|
||||
/*! @brief Clock ip name array for PWM. */
|
||||
#define PWM_CLOCKS \
|
||||
{ \
|
||||
{ \
|
||||
kCLOCK_IpInvalid, kCLOCK_IpInvalid, kCLOCK_IpInvalid, kCLOCK_IpInvalid \
|
||||
} \
|
||||
, {kCLOCK_Pwm1, kCLOCK_Pwm1, kCLOCK_Pwm1, kCLOCK_Pwm1}, {kCLOCK_Pwm2, kCLOCK_Pwm2, kCLOCK_Pwm2, kCLOCK_Pwm2}, \
|
||||
{kCLOCK_Pwm3, kCLOCK_Pwm3, kCLOCK_Pwm3, kCLOCK_Pwm3}, \
|
||||
{ \
|
||||
kCLOCK_Pwm4, kCLOCK_Pwm4, kCLOCK_Pwm4, kCLOCK_Pwm4 \
|
||||
} \
|
||||
#define PWM_CLOCKS \
|
||||
{ \
|
||||
{kCLOCK_IpInvalid, kCLOCK_IpInvalid, kCLOCK_IpInvalid, kCLOCK_IpInvalid}, \
|
||||
{kCLOCK_Pwm1, kCLOCK_Pwm1, kCLOCK_Pwm1, kCLOCK_Pwm1}, \
|
||||
{kCLOCK_Pwm2, kCLOCK_Pwm2, kCLOCK_Pwm2, kCLOCK_Pwm2}, \
|
||||
{kCLOCK_Pwm3, kCLOCK_Pwm3, kCLOCK_Pwm3, kCLOCK_Pwm3}, \
|
||||
{ \
|
||||
kCLOCK_Pwm4, kCLOCK_Pwm4, kCLOCK_Pwm4, kCLOCK_Pwm4 \
|
||||
} \
|
||||
}
|
||||
|
||||
/*! @brief Clock ip name array for PXP. */
|
||||
@@ -364,18 +415,18 @@ extern volatile uint32_t g_rtcXtalFreq;
|
||||
/*! @brief Clock name used to get clock frequency. */
|
||||
typedef enum _clock_name
|
||||
{
|
||||
kCLOCK_CpuClk = 0x0U, /*!< CPU clock */
|
||||
kCLOCK_AhbClk = 0x1U, /*!< AHB clock */
|
||||
kCLOCK_CpuClk = 0x0U, /*!< CPU clock */
|
||||
kCLOCK_AhbClk = 0x1U, /*!< AHB clock */
|
||||
kCLOCK_SemcClk = 0x2U, /*!< SEMC clock */
|
||||
kCLOCK_IpgClk = 0x3U, /*!< IPG clock */
|
||||
kCLOCK_PerClk = 0x4U, /*!< PER clock */
|
||||
kCLOCK_IpgClk = 0x3U, /*!< IPG clock */
|
||||
kCLOCK_PerClk = 0x4U, /*!< PER clock */
|
||||
|
||||
kCLOCK_OscClk = 0x5U, /*!< OSC clock selected by PMU_LOWPWR_CTRL[OSC_SEL]. */
|
||||
kCLOCK_RtcClk = 0x6U, /*!< RTC clock. (RTCCLK) */
|
||||
|
||||
kCLOCK_ArmPllClk = 0x7U, /*!< ARMPLLCLK. */
|
||||
|
||||
kCLOCK_Usb1PllClk = 0x8U, /*!< USB1PLLCLK. */
|
||||
kCLOCK_Usb1PllClk = 0x8U, /*!< USB1PLLCLK. */
|
||||
kCLOCK_Usb1PllPfd0Clk = 0x9U, /*!< USB1PLLPDF0CLK. */
|
||||
kCLOCK_Usb1PllPfd1Clk = 0xAU, /*!< USB1PLLPFD1CLK. */
|
||||
kCLOCK_Usb1PllPfd2Clk = 0xBU, /*!< USB1PLLPFD2CLK. */
|
||||
@@ -383,7 +434,7 @@ typedef enum _clock_name
|
||||
|
||||
kCLOCK_Usb2PllClk = 0xDU, /*!< USB2PLLCLK. */
|
||||
|
||||
kCLOCK_SysPllClk = 0xEU, /*!< SYSPLLCLK. */
|
||||
kCLOCK_SysPllClk = 0xEU, /*!< SYSPLLCLK. */
|
||||
kCLOCK_SysPllPfd0Clk = 0xFU, /*!< SYSPLLPDF0CLK. */
|
||||
kCLOCK_SysPllPfd1Clk = 0x10U, /*!< SYSPLLPFD1CLK. */
|
||||
kCLOCK_SysPllPfd2Clk = 0x11U, /*!< SYSPLLPFD2CLK. */
|
||||
@@ -407,151 +458,151 @@ typedef enum _clock_ip_name
|
||||
kCLOCK_IpInvalid = -1,
|
||||
|
||||
/* CCM CCGR0 */
|
||||
kCLOCK_Aips_tz1 = (0U << 8U) | CCM_CCGR0_CG0_SHIFT, /*!< CCGR0, CG0 */
|
||||
kCLOCK_Aips_tz2 = (0U << 8U) | CCM_CCGR0_CG1_SHIFT, /*!< CCGR0, CG1 */
|
||||
kCLOCK_Mqs = (0U << 8U) | CCM_CCGR0_CG2_SHIFT, /*!< CCGR0, CG2 */
|
||||
kCLOCK_FlexSpiExsc = (0U << 8U) | CCM_CCGR0_CG3_SHIFT, /*!< CCGR0, CG3 */
|
||||
kCLOCK_Sim_M_Main = (0U << 8U) | CCM_CCGR0_CG4_SHIFT, /*!< CCGR0, CG4 */
|
||||
kCLOCK_Dcp = (0U << 8U) | CCM_CCGR0_CG5_SHIFT, /*!< CCGR0, CG5 */
|
||||
kCLOCK_Lpuart3 = (0U << 8U) | CCM_CCGR0_CG6_SHIFT, /*!< CCGR0, CG6 */
|
||||
kCLOCK_Can1 = (0U << 8U) | CCM_CCGR0_CG7_SHIFT, /*!< CCGR0, CG7 */
|
||||
kCLOCK_Can1S = (0U << 8U) | CCM_CCGR0_CG8_SHIFT, /*!< CCGR0, CG8 */
|
||||
kCLOCK_Can2 = (0U << 8U) | CCM_CCGR0_CG9_SHIFT, /*!< CCGR0, CG9 */
|
||||
kCLOCK_Can2S = (0U << 8U) | CCM_CCGR0_CG10_SHIFT, /*!< CCGR0, CG10 */
|
||||
kCLOCK_Trace = (0U << 8U) | CCM_CCGR0_CG11_SHIFT, /*!< CCGR0, CG11 */
|
||||
kCLOCK_Gpt2 = (0U << 8U) | CCM_CCGR0_CG12_SHIFT, /*!< CCGR0, CG12 */
|
||||
kCLOCK_Gpt2S = (0U << 8U) | CCM_CCGR0_CG13_SHIFT, /*!< CCGR0, CG13 */
|
||||
kCLOCK_Lpuart2 = (0U << 8U) | CCM_CCGR0_CG14_SHIFT, /*!< CCGR0, CG14 */
|
||||
kCLOCK_Gpio2 = (0U << 8U) | CCM_CCGR0_CG15_SHIFT, /*!< CCGR0, CG15 */
|
||||
kCLOCK_Aips_tz1 = (0U << 8U) | CCM_CCGR0_CG0_SHIFT, /*!< CCGR0, CG0 */
|
||||
kCLOCK_Aips_tz2 = (0U << 8U) | CCM_CCGR0_CG1_SHIFT, /*!< CCGR0, CG1 */
|
||||
kCLOCK_Mqs = (0U << 8U) | CCM_CCGR0_CG2_SHIFT, /*!< CCGR0, CG2 */
|
||||
kCLOCK_FlexSpiExsc = (0U << 8U) | CCM_CCGR0_CG3_SHIFT, /*!< CCGR0, CG3 */
|
||||
kCLOCK_Sim_M_Main = (0U << 8U) | CCM_CCGR0_CG4_SHIFT, /*!< CCGR0, CG4 */
|
||||
kCLOCK_Dcp = (0U << 8U) | CCM_CCGR0_CG5_SHIFT, /*!< CCGR0, CG5 */
|
||||
kCLOCK_Lpuart3 = (0U << 8U) | CCM_CCGR0_CG6_SHIFT, /*!< CCGR0, CG6 */
|
||||
kCLOCK_Can1 = (0U << 8U) | CCM_CCGR0_CG7_SHIFT, /*!< CCGR0, CG7 */
|
||||
kCLOCK_Can1S = (0U << 8U) | CCM_CCGR0_CG8_SHIFT, /*!< CCGR0, CG8 */
|
||||
kCLOCK_Can2 = (0U << 8U) | CCM_CCGR0_CG9_SHIFT, /*!< CCGR0, CG9 */
|
||||
kCLOCK_Can2S = (0U << 8U) | CCM_CCGR0_CG10_SHIFT, /*!< CCGR0, CG10 */
|
||||
kCLOCK_Trace = (0U << 8U) | CCM_CCGR0_CG11_SHIFT, /*!< CCGR0, CG11 */
|
||||
kCLOCK_Gpt2 = (0U << 8U) | CCM_CCGR0_CG12_SHIFT, /*!< CCGR0, CG12 */
|
||||
kCLOCK_Gpt2S = (0U << 8U) | CCM_CCGR0_CG13_SHIFT, /*!< CCGR0, CG13 */
|
||||
kCLOCK_Lpuart2 = (0U << 8U) | CCM_CCGR0_CG14_SHIFT, /*!< CCGR0, CG14 */
|
||||
kCLOCK_Gpio2 = (0U << 8U) | CCM_CCGR0_CG15_SHIFT, /*!< CCGR0, CG15 */
|
||||
|
||||
/* CCM CCGR1 */
|
||||
kCLOCK_Lpspi1 = (1U << 8U) | CCM_CCGR1_CG0_SHIFT, /*!< CCGR1, CG0 */
|
||||
kCLOCK_Lpspi2 = (1U << 8U) | CCM_CCGR1_CG1_SHIFT, /*!< CCGR1, CG1 */
|
||||
kCLOCK_Lpspi3 = (1U << 8U) | CCM_CCGR1_CG2_SHIFT, /*!< CCGR1, CG2 */
|
||||
kCLOCK_Lpspi4 = (1U << 8U) | CCM_CCGR1_CG3_SHIFT, /*!< CCGR1, CG3 */
|
||||
kCLOCK_Adc2 = (1U << 8U) | CCM_CCGR1_CG4_SHIFT, /*!< CCGR1, CG4 */
|
||||
kCLOCK_Enet = (1U << 8U) | CCM_CCGR1_CG5_SHIFT, /*!< CCGR1, CG5 */
|
||||
kCLOCK_Pit = (1U << 8U) | CCM_CCGR1_CG6_SHIFT, /*!< CCGR1, CG6 */
|
||||
kCLOCK_Aoi2 = (1U << 8U) | CCM_CCGR1_CG7_SHIFT, /*!< CCGR1, CG7 */
|
||||
kCLOCK_Adc1 = (1U << 8U) | CCM_CCGR1_CG8_SHIFT, /*!< CCGR1, CG8 */
|
||||
kCLOCK_SemcExsc = (1U << 8U) | CCM_CCGR1_CG9_SHIFT, /*!< CCGR1, CG9 */
|
||||
kCLOCK_Gpt1 = (1U << 8U) | CCM_CCGR1_CG10_SHIFT, /*!< CCGR1, CG10 */
|
||||
kCLOCK_Gpt1S = (1U << 8U) | CCM_CCGR1_CG11_SHIFT, /*!< CCGR1, CG11 */
|
||||
kCLOCK_Lpuart4 = (1U << 8U) | CCM_CCGR1_CG12_SHIFT, /*!< CCGR1, CG12 */
|
||||
kCLOCK_Gpio1 = (1U << 8U) | CCM_CCGR1_CG13_SHIFT, /*!< CCGR1, CG13 */
|
||||
kCLOCK_Csu = (1U << 8U) | CCM_CCGR1_CG14_SHIFT, /*!< CCGR1, CG14 */
|
||||
kCLOCK_Gpio5 = (1U << 8U) | CCM_CCGR1_CG15_SHIFT, /*!< CCGR1, CG15 */
|
||||
kCLOCK_Lpspi1 = (1U << 8U) | CCM_CCGR1_CG0_SHIFT, /*!< CCGR1, CG0 */
|
||||
kCLOCK_Lpspi2 = (1U << 8U) | CCM_CCGR1_CG1_SHIFT, /*!< CCGR1, CG1 */
|
||||
kCLOCK_Lpspi3 = (1U << 8U) | CCM_CCGR1_CG2_SHIFT, /*!< CCGR1, CG2 */
|
||||
kCLOCK_Lpspi4 = (1U << 8U) | CCM_CCGR1_CG3_SHIFT, /*!< CCGR1, CG3 */
|
||||
kCLOCK_Adc2 = (1U << 8U) | CCM_CCGR1_CG4_SHIFT, /*!< CCGR1, CG4 */
|
||||
kCLOCK_Enet = (1U << 8U) | CCM_CCGR1_CG5_SHIFT, /*!< CCGR1, CG5 */
|
||||
kCLOCK_Pit = (1U << 8U) | CCM_CCGR1_CG6_SHIFT, /*!< CCGR1, CG6 */
|
||||
kCLOCK_Aoi2 = (1U << 8U) | CCM_CCGR1_CG7_SHIFT, /*!< CCGR1, CG7 */
|
||||
kCLOCK_Adc1 = (1U << 8U) | CCM_CCGR1_CG8_SHIFT, /*!< CCGR1, CG8 */
|
||||
kCLOCK_SemcExsc = (1U << 8U) | CCM_CCGR1_CG9_SHIFT, /*!< CCGR1, CG9 */
|
||||
kCLOCK_Gpt1 = (1U << 8U) | CCM_CCGR1_CG10_SHIFT, /*!< CCGR1, CG10 */
|
||||
kCLOCK_Gpt1S = (1U << 8U) | CCM_CCGR1_CG11_SHIFT, /*!< CCGR1, CG11 */
|
||||
kCLOCK_Lpuart4 = (1U << 8U) | CCM_CCGR1_CG12_SHIFT, /*!< CCGR1, CG12 */
|
||||
kCLOCK_Gpio1 = (1U << 8U) | CCM_CCGR1_CG13_SHIFT, /*!< CCGR1, CG13 */
|
||||
kCLOCK_Csu = (1U << 8U) | CCM_CCGR1_CG14_SHIFT, /*!< CCGR1, CG14 */
|
||||
kCLOCK_Gpio5 = (1U << 8U) | CCM_CCGR1_CG15_SHIFT, /*!< CCGR1, CG15 */
|
||||
|
||||
/* CCM CCGR2 */
|
||||
kCLOCK_OcramExsc = (2U << 8U) | CCM_CCGR2_CG0_SHIFT, /*!< CCGR2, CG0 */
|
||||
kCLOCK_Csi = (2U << 8U) | CCM_CCGR2_CG1_SHIFT, /*!< CCGR2, CG1 */
|
||||
kCLOCK_IomuxcSnvs = (2U << 8U) | CCM_CCGR2_CG2_SHIFT, /*!< CCGR2, CG2 */
|
||||
kCLOCK_Lpi2c1 = (2U << 8U) | CCM_CCGR2_CG3_SHIFT, /*!< CCGR2, CG3 */
|
||||
kCLOCK_Lpi2c2 = (2U << 8U) | CCM_CCGR2_CG4_SHIFT, /*!< CCGR2, CG4 */
|
||||
kCLOCK_Lpi2c3 = (2U << 8U) | CCM_CCGR2_CG5_SHIFT, /*!< CCGR2, CG5 */
|
||||
kCLOCK_Ocotp = (2U << 8U) | CCM_CCGR2_CG6_SHIFT, /*!< CCGR2, CG6 */
|
||||
kCLOCK_Xbar3 = (2U << 8U) | CCM_CCGR2_CG7_SHIFT, /*!< CCGR2, CG7 */
|
||||
kCLOCK_Ipmux1 = (2U << 8U) | CCM_CCGR2_CG8_SHIFT, /*!< CCGR2, CG8 */
|
||||
kCLOCK_Ipmux2 = (2U << 8U) | CCM_CCGR2_CG9_SHIFT, /*!< CCGR2, CG9 */
|
||||
kCLOCK_Ipmux3 = (2U << 8U) | CCM_CCGR2_CG10_SHIFT, /*!< CCGR2, CG10 */
|
||||
kCLOCK_Xbar1 = (2U << 8U) | CCM_CCGR2_CG11_SHIFT, /*!< CCGR2, CG11 */
|
||||
kCLOCK_Xbar2 = (2U << 8U) | CCM_CCGR2_CG12_SHIFT, /*!< CCGR2, CG12 */
|
||||
kCLOCK_Gpio3 = (2U << 8U) | CCM_CCGR2_CG13_SHIFT, /*!< CCGR2, CG13 */
|
||||
kCLOCK_Lcd = (2U << 8U) | CCM_CCGR2_CG14_SHIFT, /*!< CCGR2, CG14 */
|
||||
kCLOCK_Pxp = (2U << 8U) | CCM_CCGR2_CG15_SHIFT, /*!< CCGR2, CG15 */
|
||||
kCLOCK_OcramExsc = (2U << 8U) | CCM_CCGR2_CG0_SHIFT, /*!< CCGR2, CG0 */
|
||||
kCLOCK_Csi = (2U << 8U) | CCM_CCGR2_CG1_SHIFT, /*!< CCGR2, CG1 */
|
||||
kCLOCK_IomuxcSnvs = (2U << 8U) | CCM_CCGR2_CG2_SHIFT, /*!< CCGR2, CG2 */
|
||||
kCLOCK_Lpi2c1 = (2U << 8U) | CCM_CCGR2_CG3_SHIFT, /*!< CCGR2, CG3 */
|
||||
kCLOCK_Lpi2c2 = (2U << 8U) | CCM_CCGR2_CG4_SHIFT, /*!< CCGR2, CG4 */
|
||||
kCLOCK_Lpi2c3 = (2U << 8U) | CCM_CCGR2_CG5_SHIFT, /*!< CCGR2, CG5 */
|
||||
kCLOCK_Ocotp = (2U << 8U) | CCM_CCGR2_CG6_SHIFT, /*!< CCGR2, CG6 */
|
||||
kCLOCK_Xbar3 = (2U << 8U) | CCM_CCGR2_CG7_SHIFT, /*!< CCGR2, CG7 */
|
||||
kCLOCK_Ipmux1 = (2U << 8U) | CCM_CCGR2_CG8_SHIFT, /*!< CCGR2, CG8 */
|
||||
kCLOCK_Ipmux2 = (2U << 8U) | CCM_CCGR2_CG9_SHIFT, /*!< CCGR2, CG9 */
|
||||
kCLOCK_Ipmux3 = (2U << 8U) | CCM_CCGR2_CG10_SHIFT, /*!< CCGR2, CG10 */
|
||||
kCLOCK_Xbar1 = (2U << 8U) | CCM_CCGR2_CG11_SHIFT, /*!< CCGR2, CG11 */
|
||||
kCLOCK_Xbar2 = (2U << 8U) | CCM_CCGR2_CG12_SHIFT, /*!< CCGR2, CG12 */
|
||||
kCLOCK_Gpio3 = (2U << 8U) | CCM_CCGR2_CG13_SHIFT, /*!< CCGR2, CG13 */
|
||||
kCLOCK_Lcd = (2U << 8U) | CCM_CCGR2_CG14_SHIFT, /*!< CCGR2, CG14 */
|
||||
kCLOCK_Pxp = (2U << 8U) | CCM_CCGR2_CG15_SHIFT, /*!< CCGR2, CG15 */
|
||||
|
||||
/* CCM CCGR3 */
|
||||
kCLOCK_Flexio2 = (3U << 8U) | CCM_CCGR3_CG0_SHIFT, /*!< CCGR3, CG0 */
|
||||
kCLOCK_Lpuart5 = (3U << 8U) | CCM_CCGR3_CG1_SHIFT, /*!< CCGR3, CG1 */
|
||||
kCLOCK_Semc = (3U << 8U) | CCM_CCGR3_CG2_SHIFT, /*!< CCGR3, CG2 */
|
||||
kCLOCK_Lpuart6 = (3U << 8U) | CCM_CCGR3_CG3_SHIFT, /*!< CCGR3, CG3 */
|
||||
kCLOCK_Aoi1 = (3U << 8U) | CCM_CCGR3_CG4_SHIFT, /*!< CCGR3, CG4 */
|
||||
kCLOCK_LcdPixel = (3U << 8U) | CCM_CCGR3_CG5_SHIFT, /*!< CCGR3, CG5 */
|
||||
kCLOCK_Gpio4 = (3U << 8U) | CCM_CCGR3_CG6_SHIFT, /*!< CCGR3, CG6 */
|
||||
kCLOCK_Ewm0 = (3U << 8U) | CCM_CCGR3_CG7_SHIFT, /*!< CCGR3, CG7 */
|
||||
kCLOCK_Wdog1 = (3U << 8U) | CCM_CCGR3_CG8_SHIFT, /*!< CCGR3, CG8 */
|
||||
kCLOCK_FlexRam = (3U << 8U) | CCM_CCGR3_CG9_SHIFT, /*!< CCGR3, CG9 */
|
||||
kCLOCK_Acmp1 = (3U << 8U) | CCM_CCGR3_CG10_SHIFT, /*!< CCGR3, CG10 */
|
||||
kCLOCK_Acmp2 = (3U << 8U) | CCM_CCGR3_CG11_SHIFT, /*!< CCGR3, CG11 */
|
||||
kCLOCK_Acmp3 = (3U << 8U) | CCM_CCGR3_CG12_SHIFT, /*!< CCGR3, CG12 */
|
||||
kCLOCK_Acmp4 = (3U << 8U) | CCM_CCGR3_CG13_SHIFT, /*!< CCGR3, CG13 */
|
||||
kCLOCK_Ocram = (3U << 8U) | CCM_CCGR3_CG14_SHIFT, /*!< CCGR3, CG14 */
|
||||
kCLOCK_Flexio2 = (3U << 8U) | CCM_CCGR3_CG0_SHIFT, /*!< CCGR3, CG0 */
|
||||
kCLOCK_Lpuart5 = (3U << 8U) | CCM_CCGR3_CG1_SHIFT, /*!< CCGR3, CG1 */
|
||||
kCLOCK_Semc = (3U << 8U) | CCM_CCGR3_CG2_SHIFT, /*!< CCGR3, CG2 */
|
||||
kCLOCK_Lpuart6 = (3U << 8U) | CCM_CCGR3_CG3_SHIFT, /*!< CCGR3, CG3 */
|
||||
kCLOCK_Aoi1 = (3U << 8U) | CCM_CCGR3_CG4_SHIFT, /*!< CCGR3, CG4 */
|
||||
kCLOCK_LcdPixel = (3U << 8U) | CCM_CCGR3_CG5_SHIFT, /*!< CCGR3, CG5 */
|
||||
kCLOCK_Gpio4 = (3U << 8U) | CCM_CCGR3_CG6_SHIFT, /*!< CCGR3, CG6 */
|
||||
kCLOCK_Ewm0 = (3U << 8U) | CCM_CCGR3_CG7_SHIFT, /*!< CCGR3, CG7 */
|
||||
kCLOCK_Wdog1 = (3U << 8U) | CCM_CCGR3_CG8_SHIFT, /*!< CCGR3, CG8 */
|
||||
kCLOCK_FlexRam = (3U << 8U) | CCM_CCGR3_CG9_SHIFT, /*!< CCGR3, CG9 */
|
||||
kCLOCK_Acmp1 = (3U << 8U) | CCM_CCGR3_CG10_SHIFT, /*!< CCGR3, CG10 */
|
||||
kCLOCK_Acmp2 = (3U << 8U) | CCM_CCGR3_CG11_SHIFT, /*!< CCGR3, CG11 */
|
||||
kCLOCK_Acmp3 = (3U << 8U) | CCM_CCGR3_CG12_SHIFT, /*!< CCGR3, CG12 */
|
||||
kCLOCK_Acmp4 = (3U << 8U) | CCM_CCGR3_CG13_SHIFT, /*!< CCGR3, CG13 */
|
||||
kCLOCK_Ocram = (3U << 8U) | CCM_CCGR3_CG14_SHIFT, /*!< CCGR3, CG14 */
|
||||
kCLOCK_IomuxcSnvsGpr = (3U << 8U) | CCM_CCGR3_CG15_SHIFT, /*!< CCGR3, CG15 */
|
||||
|
||||
/* CCM CCGR4 */
|
||||
kCLOCK_Iomuxc = (4U << 8U) | CCM_CCGR4_CG1_SHIFT, /*!< CCGR4, CG1 */
|
||||
kCLOCK_IomuxcGpr = (4U << 8U) | CCM_CCGR4_CG2_SHIFT, /*!< CCGR4, CG2 */
|
||||
kCLOCK_Bee = (4U << 8U) | CCM_CCGR4_CG3_SHIFT, /*!< CCGR4, CG3 */
|
||||
kCLOCK_SimM7 = (4U << 8U) | CCM_CCGR4_CG4_SHIFT, /*!< CCGR4, CG4 */
|
||||
kCLOCK_Tsc = (4U << 8U) | CCM_CCGR4_CG5_SHIFT, /*!< CCGR4, CG5 */
|
||||
kCLOCK_SimM = (4U << 8U) | CCM_CCGR4_CG6_SHIFT, /*!< CCGR4, CG6 */
|
||||
kCLOCK_SimEms = (4U << 8U) | CCM_CCGR4_CG7_SHIFT, /*!< CCGR4, CG7 */
|
||||
kCLOCK_Pwm1 = (4U << 8U) | CCM_CCGR4_CG8_SHIFT, /*!< CCGR4, CG8 */
|
||||
kCLOCK_Pwm2 = (4U << 8U) | CCM_CCGR4_CG9_SHIFT, /*!< CCGR4, CG9 */
|
||||
kCLOCK_Pwm3 = (4U << 8U) | CCM_CCGR4_CG10_SHIFT, /*!< CCGR4, CG10 */
|
||||
kCLOCK_Pwm4 = (4U << 8U) | CCM_CCGR4_CG11_SHIFT, /*!< CCGR4, CG11 */
|
||||
kCLOCK_Enc1 = (4U << 8U) | CCM_CCGR4_CG12_SHIFT, /*!< CCGR4, CG12 */
|
||||
kCLOCK_Enc2 = (4U << 8U) | CCM_CCGR4_CG13_SHIFT, /*!< CCGR4, CG13 */
|
||||
kCLOCK_Enc3 = (4U << 8U) | CCM_CCGR4_CG14_SHIFT, /*!< CCGR4, CG14 */
|
||||
kCLOCK_Enc4 = (4U << 8U) | CCM_CCGR4_CG15_SHIFT, /*!< CCGR4, CG15 */
|
||||
kCLOCK_Iomuxc = (4U << 8U) | CCM_CCGR4_CG1_SHIFT, /*!< CCGR4, CG1 */
|
||||
kCLOCK_IomuxcGpr = (4U << 8U) | CCM_CCGR4_CG2_SHIFT, /*!< CCGR4, CG2 */
|
||||
kCLOCK_Bee = (4U << 8U) | CCM_CCGR4_CG3_SHIFT, /*!< CCGR4, CG3 */
|
||||
kCLOCK_SimM7 = (4U << 8U) | CCM_CCGR4_CG4_SHIFT, /*!< CCGR4, CG4 */
|
||||
kCLOCK_Tsc = (4U << 8U) | CCM_CCGR4_CG5_SHIFT, /*!< CCGR4, CG5 */
|
||||
kCLOCK_SimM = (4U << 8U) | CCM_CCGR4_CG6_SHIFT, /*!< CCGR4, CG6 */
|
||||
kCLOCK_SimEms = (4U << 8U) | CCM_CCGR4_CG7_SHIFT, /*!< CCGR4, CG7 */
|
||||
kCLOCK_Pwm1 = (4U << 8U) | CCM_CCGR4_CG8_SHIFT, /*!< CCGR4, CG8 */
|
||||
kCLOCK_Pwm2 = (4U << 8U) | CCM_CCGR4_CG9_SHIFT, /*!< CCGR4, CG9 */
|
||||
kCLOCK_Pwm3 = (4U << 8U) | CCM_CCGR4_CG10_SHIFT, /*!< CCGR4, CG10 */
|
||||
kCLOCK_Pwm4 = (4U << 8U) | CCM_CCGR4_CG11_SHIFT, /*!< CCGR4, CG11 */
|
||||
kCLOCK_Enc1 = (4U << 8U) | CCM_CCGR4_CG12_SHIFT, /*!< CCGR4, CG12 */
|
||||
kCLOCK_Enc2 = (4U << 8U) | CCM_CCGR4_CG13_SHIFT, /*!< CCGR4, CG13 */
|
||||
kCLOCK_Enc3 = (4U << 8U) | CCM_CCGR4_CG14_SHIFT, /*!< CCGR4, CG14 */
|
||||
kCLOCK_Enc4 = (4U << 8U) | CCM_CCGR4_CG15_SHIFT, /*!< CCGR4, CG15 */
|
||||
|
||||
/* CCM CCGR5 */
|
||||
kCLOCK_Rom = (5U << 8U) | CCM_CCGR5_CG0_SHIFT, /*!< CCGR5, CG0 */
|
||||
kCLOCK_Flexio1 = (5U << 8U) | CCM_CCGR5_CG1_SHIFT, /*!< CCGR5, CG1 */
|
||||
kCLOCK_Wdog3 = (5U << 8U) | CCM_CCGR5_CG2_SHIFT, /*!< CCGR5, CG2 */
|
||||
kCLOCK_Dma = (5U << 8U) | CCM_CCGR5_CG3_SHIFT, /*!< CCGR5, CG3 */
|
||||
kCLOCK_Kpp = (5U << 8U) | CCM_CCGR5_CG4_SHIFT, /*!< CCGR5, CG4 */
|
||||
kCLOCK_Wdog2 = (5U << 8U) | CCM_CCGR5_CG5_SHIFT, /*!< CCGR5, CG5 */
|
||||
kCLOCK_Aips_tz4 = (5U << 8U) | CCM_CCGR5_CG6_SHIFT, /*!< CCGR5, CG6 */
|
||||
kCLOCK_Spdif = (5U << 8U) | CCM_CCGR5_CG7_SHIFT, /*!< CCGR5, CG7 */
|
||||
kCLOCK_SimMain = (5U << 8U) | CCM_CCGR5_CG8_SHIFT, /*!< CCGR5, CG8 */
|
||||
kCLOCK_Sai1 = (5U << 8U) | CCM_CCGR5_CG9_SHIFT, /*!< CCGR5, CG9 */
|
||||
kCLOCK_Sai2 = (5U << 8U) | CCM_CCGR5_CG10_SHIFT, /*!< CCGR5, CG10 */
|
||||
kCLOCK_Sai3 = (5U << 8U) | CCM_CCGR5_CG11_SHIFT, /*!< CCGR5, CG11 */
|
||||
kCLOCK_Lpuart1 = (5U << 8U) | CCM_CCGR5_CG12_SHIFT, /*!< CCGR5, CG12 */
|
||||
kCLOCK_Lpuart7 = (5U << 8U) | CCM_CCGR5_CG13_SHIFT, /*!< CCGR5, CG13 */
|
||||
kCLOCK_SnvsHp = (5U << 8U) | CCM_CCGR5_CG14_SHIFT, /*!< CCGR5, CG14 */
|
||||
kCLOCK_SnvsLp = (5U << 8U) | CCM_CCGR5_CG15_SHIFT, /*!< CCGR5, CG15 */
|
||||
kCLOCK_Rom = (5U << 8U) | CCM_CCGR5_CG0_SHIFT, /*!< CCGR5, CG0 */
|
||||
kCLOCK_Flexio1 = (5U << 8U) | CCM_CCGR5_CG1_SHIFT, /*!< CCGR5, CG1 */
|
||||
kCLOCK_Wdog3 = (5U << 8U) | CCM_CCGR5_CG2_SHIFT, /*!< CCGR5, CG2 */
|
||||
kCLOCK_Dma = (5U << 8U) | CCM_CCGR5_CG3_SHIFT, /*!< CCGR5, CG3 */
|
||||
kCLOCK_Kpp = (5U << 8U) | CCM_CCGR5_CG4_SHIFT, /*!< CCGR5, CG4 */
|
||||
kCLOCK_Wdog2 = (5U << 8U) | CCM_CCGR5_CG5_SHIFT, /*!< CCGR5, CG5 */
|
||||
kCLOCK_Aips_tz4 = (5U << 8U) | CCM_CCGR5_CG6_SHIFT, /*!< CCGR5, CG6 */
|
||||
kCLOCK_Spdif = (5U << 8U) | CCM_CCGR5_CG7_SHIFT, /*!< CCGR5, CG7 */
|
||||
kCLOCK_SimMain = (5U << 8U) | CCM_CCGR5_CG8_SHIFT, /*!< CCGR5, CG8 */
|
||||
kCLOCK_Sai1 = (5U << 8U) | CCM_CCGR5_CG9_SHIFT, /*!< CCGR5, CG9 */
|
||||
kCLOCK_Sai2 = (5U << 8U) | CCM_CCGR5_CG10_SHIFT, /*!< CCGR5, CG10 */
|
||||
kCLOCK_Sai3 = (5U << 8U) | CCM_CCGR5_CG11_SHIFT, /*!< CCGR5, CG11 */
|
||||
kCLOCK_Lpuart1 = (5U << 8U) | CCM_CCGR5_CG12_SHIFT, /*!< CCGR5, CG12 */
|
||||
kCLOCK_Lpuart7 = (5U << 8U) | CCM_CCGR5_CG13_SHIFT, /*!< CCGR5, CG13 */
|
||||
kCLOCK_SnvsHp = (5U << 8U) | CCM_CCGR5_CG14_SHIFT, /*!< CCGR5, CG14 */
|
||||
kCLOCK_SnvsLp = (5U << 8U) | CCM_CCGR5_CG15_SHIFT, /*!< CCGR5, CG15 */
|
||||
|
||||
/* CCM CCGR6 */
|
||||
kCLOCK_UsbOh3 = (6U << 8U) | CCM_CCGR6_CG0_SHIFT, /*!< CCGR6, CG0 */
|
||||
kCLOCK_Usdhc1 = (6U << 8U) | CCM_CCGR6_CG1_SHIFT, /*!< CCGR6, CG1 */
|
||||
kCLOCK_Usdhc2 = (6U << 8U) | CCM_CCGR6_CG2_SHIFT, /*!< CCGR6, CG2 */
|
||||
kCLOCK_Dcdc = (6U << 8U) | CCM_CCGR6_CG3_SHIFT, /*!< CCGR6, CG3 */
|
||||
kCLOCK_Ipmux4 = (6U << 8U) | CCM_CCGR6_CG4_SHIFT, /*!< CCGR6, CG4 */
|
||||
kCLOCK_FlexSpi = (6U << 8U) | CCM_CCGR6_CG5_SHIFT, /*!< CCGR6, CG5 */
|
||||
kCLOCK_Trng = (6U << 8U) | CCM_CCGR6_CG6_SHIFT, /*!< CCGR6, CG6 */
|
||||
kCLOCK_Lpuart8 = (6U << 8U) | CCM_CCGR6_CG7_SHIFT, /*!< CCGR6, CG7 */
|
||||
kCLOCK_Timer4 = (6U << 8U) | CCM_CCGR6_CG8_SHIFT, /*!< CCGR6, CG8 */
|
||||
kCLOCK_Aips_tz3 = (6U << 8U) | CCM_CCGR6_CG9_SHIFT, /*!< CCGR6, CG9 */
|
||||
kCLOCK_SimPer = (6U << 8U) | CCM_CCGR6_CG10_SHIFT, /*!< CCGR6, CG10 */
|
||||
kCLOCK_Anadig = (6U << 8U) | CCM_CCGR6_CG11_SHIFT, /*!< CCGR6, CG11 */
|
||||
kCLOCK_Lpi2c4 = (6U << 8U) | CCM_CCGR6_CG12_SHIFT, /*!< CCGR6, CG12 */
|
||||
kCLOCK_Timer1 = (6U << 8U) | CCM_CCGR6_CG13_SHIFT, /*!< CCGR6, CG13 */
|
||||
kCLOCK_Timer2 = (6U << 8U) | CCM_CCGR6_CG14_SHIFT, /*!< CCGR6, CG14 */
|
||||
kCLOCK_Timer3 = (6U << 8U) | CCM_CCGR6_CG15_SHIFT, /*!< CCGR6, CG15 */
|
||||
kCLOCK_UsbOh3 = (6U << 8U) | CCM_CCGR6_CG0_SHIFT, /*!< CCGR6, CG0 */
|
||||
kCLOCK_Usdhc1 = (6U << 8U) | CCM_CCGR6_CG1_SHIFT, /*!< CCGR6, CG1 */
|
||||
kCLOCK_Usdhc2 = (6U << 8U) | CCM_CCGR6_CG2_SHIFT, /*!< CCGR6, CG2 */
|
||||
kCLOCK_Dcdc = (6U << 8U) | CCM_CCGR6_CG3_SHIFT, /*!< CCGR6, CG3 */
|
||||
kCLOCK_Ipmux4 = (6U << 8U) | CCM_CCGR6_CG4_SHIFT, /*!< CCGR6, CG4 */
|
||||
kCLOCK_FlexSpi = (6U << 8U) | CCM_CCGR6_CG5_SHIFT, /*!< CCGR6, CG5 */
|
||||
kCLOCK_Trng = (6U << 8U) | CCM_CCGR6_CG6_SHIFT, /*!< CCGR6, CG6 */
|
||||
kCLOCK_Lpuart8 = (6U << 8U) | CCM_CCGR6_CG7_SHIFT, /*!< CCGR6, CG7 */
|
||||
kCLOCK_Timer4 = (6U << 8U) | CCM_CCGR6_CG8_SHIFT, /*!< CCGR6, CG8 */
|
||||
kCLOCK_Aips_tz3 = (6U << 8U) | CCM_CCGR6_CG9_SHIFT, /*!< CCGR6, CG9 */
|
||||
kCLOCK_SimPer = (6U << 8U) | CCM_CCGR6_CG10_SHIFT, /*!< CCGR6, CG10 */
|
||||
kCLOCK_Anadig = (6U << 8U) | CCM_CCGR6_CG11_SHIFT, /*!< CCGR6, CG11 */
|
||||
kCLOCK_Lpi2c4 = (6U << 8U) | CCM_CCGR6_CG12_SHIFT, /*!< CCGR6, CG12 */
|
||||
kCLOCK_Timer1 = (6U << 8U) | CCM_CCGR6_CG13_SHIFT, /*!< CCGR6, CG13 */
|
||||
kCLOCK_Timer2 = (6U << 8U) | CCM_CCGR6_CG14_SHIFT, /*!< CCGR6, CG14 */
|
||||
kCLOCK_Timer3 = (6U << 8U) | CCM_CCGR6_CG15_SHIFT, /*!< CCGR6, CG15 */
|
||||
|
||||
} clock_ip_name_t;
|
||||
|
||||
/*! @brief OSC 24M sorce select */
|
||||
typedef enum _clock_osc
|
||||
{
|
||||
kCLOCK_RcOsc = 0U, /*!< On chip OSC. */
|
||||
kCLOCK_RcOsc = 0U, /*!< On chip OSC. */
|
||||
kCLOCK_XtalOsc = 1U, /*!< 24M Xtal OSC */
|
||||
} clock_osc_t;
|
||||
|
||||
/*! @brief Clock gate value */
|
||||
typedef enum _clock_gate_value
|
||||
{
|
||||
kCLOCK_ClockNotNeeded = 0U, /*!< Clock is off during all modes. */
|
||||
kCLOCK_ClockNeededRun = 1U, /*!< Clock is on in run mode, but off in WAIT and STOP modes */
|
||||
kCLOCK_ClockNotNeeded = 0U, /*!< Clock is off during all modes. */
|
||||
kCLOCK_ClockNeededRun = 1U, /*!< Clock is on in run mode, but off in WAIT and STOP modes */
|
||||
kCLOCK_ClockNeededRunWait = 3U, /*!< Clock is on during all modes, except STOP mode */
|
||||
} clock_gate_value_t;
|
||||
|
||||
/*! @brief System clock mode */
|
||||
typedef enum _clock_mode_t
|
||||
{
|
||||
kCLOCK_ModeRun = 0U, /*!< Remain in run mode. */
|
||||
kCLOCK_ModeRun = 0U, /*!< Remain in run mode. */
|
||||
kCLOCK_ModeWait = 1U, /*!< Transfer to wait mode. */
|
||||
kCLOCK_ModeStop = 2U, /*!< Transfer to stop mode. */
|
||||
} clock_mode_t;
|
||||
@@ -566,84 +617,106 @@ typedef enum _clock_mode_t
|
||||
*/
|
||||
typedef enum _clock_mux
|
||||
{
|
||||
kCLOCK_Pll3SwMux = CCM_TUPLE(CCSR,
|
||||
kCLOCK_Pll3SwMux = CCM_TUPLE(CCSR_OFFSET,
|
||||
CCM_CCSR_PLL3_SW_CLK_SEL_SHIFT,
|
||||
CCM_CCSR_PLL3_SW_CLK_SEL_MASK,
|
||||
CCM_NO_BUSY_WAIT), /*!< pll3_sw_clk mux name */
|
||||
|
||||
kCLOCK_PeriphMux = CCM_TUPLE(CBCDR,
|
||||
kCLOCK_PeriphMux = CCM_TUPLE(CBCDR_OFFSET,
|
||||
CCM_CBCDR_PERIPH_CLK_SEL_SHIFT,
|
||||
CCM_CBCDR_PERIPH_CLK_SEL_MASK,
|
||||
CCM_CDHIPR_PERIPH_CLK_SEL_BUSY_SHIFT), /*!< periph mux name */
|
||||
kCLOCK_SemcAltMux = CCM_TUPLE(CBCDR,
|
||||
kCLOCK_SemcAltMux = CCM_TUPLE(CBCDR_OFFSET,
|
||||
CCM_CBCDR_SEMC_ALT_CLK_SEL_SHIFT,
|
||||
CCM_CBCDR_SEMC_ALT_CLK_SEL_MASK,
|
||||
CCM_NO_BUSY_WAIT), /*!< semc mux name */
|
||||
kCLOCK_SemcMux = CCM_TUPLE(
|
||||
CBCDR, CCM_CBCDR_SEMC_CLK_SEL_SHIFT, CCM_CBCDR_SEMC_CLK_SEL_MASK, CCM_NO_BUSY_WAIT), /*!< semc mux name */
|
||||
kCLOCK_SemcMux = CCM_TUPLE(CBCDR_OFFSET,
|
||||
CCM_CBCDR_SEMC_CLK_SEL_SHIFT,
|
||||
CCM_CBCDR_SEMC_CLK_SEL_MASK,
|
||||
CCM_NO_BUSY_WAIT), /*!< semc mux name */
|
||||
|
||||
kCLOCK_PrePeriphMux = CCM_TUPLE(CBCMR,
|
||||
kCLOCK_PrePeriphMux = CCM_TUPLE(CBCMR_OFFSET,
|
||||
CCM_CBCMR_PRE_PERIPH_CLK_SEL_SHIFT,
|
||||
CCM_CBCMR_PRE_PERIPH_CLK_SEL_MASK,
|
||||
CCM_NO_BUSY_WAIT), /*!< pre-periph mux name */
|
||||
kCLOCK_TraceMux = CCM_TUPLE(
|
||||
CBCMR, CCM_CBCMR_TRACE_CLK_SEL_SHIFT, CCM_CBCMR_TRACE_CLK_SEL_MASK, CCM_NO_BUSY_WAIT), /*!< trace mux name */
|
||||
kCLOCK_PeriphClk2Mux = CCM_TUPLE(CBCMR,
|
||||
kCLOCK_TraceMux = CCM_TUPLE(CBCMR_OFFSET,
|
||||
CCM_CBCMR_TRACE_CLK_SEL_SHIFT,
|
||||
CCM_CBCMR_TRACE_CLK_SEL_MASK,
|
||||
CCM_NO_BUSY_WAIT), /*!< trace mux name */
|
||||
kCLOCK_PeriphClk2Mux = CCM_TUPLE(CBCMR_OFFSET,
|
||||
CCM_CBCMR_PERIPH_CLK2_SEL_SHIFT,
|
||||
CCM_CBCMR_PERIPH_CLK2_SEL_MASK,
|
||||
CCM_NO_BUSY_WAIT), /*!< periph clock2 mux name */
|
||||
kCLOCK_LpspiMux = CCM_TUPLE(
|
||||
CBCMR, CCM_CBCMR_LPSPI_CLK_SEL_SHIFT, CCM_CBCMR_LPSPI_CLK_SEL_MASK, CCM_NO_BUSY_WAIT), /*!< lpspi mux name */
|
||||
kCLOCK_LpspiMux = CCM_TUPLE(CBCMR_OFFSET,
|
||||
CCM_CBCMR_LPSPI_CLK_SEL_SHIFT,
|
||||
CCM_CBCMR_LPSPI_CLK_SEL_MASK,
|
||||
CCM_NO_BUSY_WAIT), /*!< lpspi mux name */
|
||||
|
||||
kCLOCK_FlexspiMux = CCM_TUPLE(CSCMR1,
|
||||
kCLOCK_FlexspiMux = CCM_TUPLE(CSCMR1_OFFSET,
|
||||
CCM_CSCMR1_FLEXSPI_CLK_SEL_SHIFT,
|
||||
CCM_CSCMR1_FLEXSPI_CLK_SEL_MASK,
|
||||
CCM_NO_BUSY_WAIT), /*!< flexspi mux name */
|
||||
kCLOCK_Usdhc2Mux = CCM_TUPLE(CSCMR1,
|
||||
kCLOCK_Usdhc2Mux = CCM_TUPLE(CSCMR1_OFFSET,
|
||||
CCM_CSCMR1_USDHC2_CLK_SEL_SHIFT,
|
||||
CCM_CSCMR1_USDHC2_CLK_SEL_MASK,
|
||||
CCM_NO_BUSY_WAIT), /*!< usdhc2 mux name */
|
||||
kCLOCK_Usdhc1Mux = CCM_TUPLE(CSCMR1,
|
||||
kCLOCK_Usdhc1Mux = CCM_TUPLE(CSCMR1_OFFSET,
|
||||
CCM_CSCMR1_USDHC1_CLK_SEL_SHIFT,
|
||||
CCM_CSCMR1_USDHC1_CLK_SEL_MASK,
|
||||
CCM_NO_BUSY_WAIT), /*!< usdhc1 mux name */
|
||||
kCLOCK_Sai3Mux = CCM_TUPLE(
|
||||
CSCMR1, CCM_CSCMR1_SAI3_CLK_SEL_SHIFT, CCM_CSCMR1_SAI3_CLK_SEL_MASK, CCM_NO_BUSY_WAIT), /*!< sai3 mux name */
|
||||
kCLOCK_Sai2Mux = CCM_TUPLE(
|
||||
CSCMR1, CCM_CSCMR1_SAI2_CLK_SEL_SHIFT, CCM_CSCMR1_SAI2_CLK_SEL_MASK, CCM_NO_BUSY_WAIT), /*!< sai2 mux name */
|
||||
kCLOCK_Sai1Mux = CCM_TUPLE(
|
||||
CSCMR1, CCM_CSCMR1_SAI1_CLK_SEL_SHIFT, CCM_CSCMR1_SAI1_CLK_SEL_MASK, CCM_NO_BUSY_WAIT), /*!< sai1 mux name */
|
||||
kCLOCK_PerclkMux = CCM_TUPLE(CSCMR1,
|
||||
kCLOCK_Sai3Mux = CCM_TUPLE(CSCMR1_OFFSET,
|
||||
CCM_CSCMR1_SAI3_CLK_SEL_SHIFT,
|
||||
CCM_CSCMR1_SAI3_CLK_SEL_MASK,
|
||||
CCM_NO_BUSY_WAIT), /*!< sai3 mux name */
|
||||
kCLOCK_Sai2Mux = CCM_TUPLE(CSCMR1_OFFSET,
|
||||
CCM_CSCMR1_SAI2_CLK_SEL_SHIFT,
|
||||
CCM_CSCMR1_SAI2_CLK_SEL_MASK,
|
||||
CCM_NO_BUSY_WAIT), /*!< sai2 mux name */
|
||||
kCLOCK_Sai1Mux = CCM_TUPLE(CSCMR1_OFFSET,
|
||||
CCM_CSCMR1_SAI1_CLK_SEL_SHIFT,
|
||||
CCM_CSCMR1_SAI1_CLK_SEL_MASK,
|
||||
CCM_NO_BUSY_WAIT), /*!< sai1 mux name */
|
||||
kCLOCK_PerclkMux = CCM_TUPLE(CSCMR1_OFFSET,
|
||||
CCM_CSCMR1_PERCLK_CLK_SEL_SHIFT,
|
||||
CCM_CSCMR1_PERCLK_CLK_SEL_MASK,
|
||||
CCM_NO_BUSY_WAIT), /*!< perclk mux name */
|
||||
|
||||
kCLOCK_Flexio2Mux = CCM_TUPLE(CSCMR2,
|
||||
kCLOCK_Flexio2Mux = CCM_TUPLE(CSCMR2_OFFSET,
|
||||
CCM_CSCMR2_FLEXIO2_CLK_SEL_SHIFT,
|
||||
CCM_CSCMR2_FLEXIO2_CLK_SEL_MASK,
|
||||
CCM_NO_BUSY_WAIT), /*!< flexio2 mux name */
|
||||
kCLOCK_CanMux = CCM_TUPLE(
|
||||
CSCMR2, CCM_CSCMR2_CAN_CLK_SEL_SHIFT, CCM_CSCMR2_CAN_CLK_SEL_MASK, CCM_NO_BUSY_WAIT), /*!< can mux name */
|
||||
kCLOCK_CanMux = CCM_TUPLE(CSCMR2_OFFSET,
|
||||
CCM_CSCMR2_CAN_CLK_SEL_SHIFT,
|
||||
CCM_CSCMR2_CAN_CLK_SEL_MASK,
|
||||
CCM_NO_BUSY_WAIT), /*!< can mux name */
|
||||
|
||||
kCLOCK_UartMux = CCM_TUPLE(
|
||||
CSCDR1, CCM_CSCDR1_UART_CLK_SEL_SHIFT, CCM_CSCDR1_UART_CLK_SEL_MASK, CCM_NO_BUSY_WAIT), /*!< uart mux name */
|
||||
kCLOCK_UartMux = CCM_TUPLE(CSCDR1_OFFSET,
|
||||
CCM_CSCDR1_UART_CLK_SEL_SHIFT,
|
||||
CCM_CSCDR1_UART_CLK_SEL_MASK,
|
||||
CCM_NO_BUSY_WAIT), /*!< uart mux name */
|
||||
|
||||
kCLOCK_SpdifMux = CCM_TUPLE(
|
||||
CDCDR, CCM_CDCDR_SPDIF0_CLK_SEL_SHIFT, CCM_CDCDR_SPDIF0_CLK_SEL_MASK, CCM_NO_BUSY_WAIT), /*!< spdif mux name */
|
||||
kCLOCK_Flexio1Mux = CCM_TUPLE(CDCDR,
|
||||
kCLOCK_SpdifMux = CCM_TUPLE(CDCDR_OFFSET,
|
||||
CCM_CDCDR_SPDIF0_CLK_SEL_SHIFT,
|
||||
CCM_CDCDR_SPDIF0_CLK_SEL_MASK,
|
||||
CCM_NO_BUSY_WAIT), /*!< spdif mux name */
|
||||
kCLOCK_Flexio1Mux = CCM_TUPLE(CDCDR_OFFSET,
|
||||
CCM_CDCDR_FLEXIO1_CLK_SEL_SHIFT,
|
||||
CCM_CDCDR_FLEXIO1_CLK_SEL_MASK,
|
||||
CCM_NO_BUSY_WAIT), /*!< flexio1 mux name */
|
||||
|
||||
kCLOCK_Lpi2cMux = CCM_TUPLE(
|
||||
CSCDR2, CCM_CSCDR2_LPI2C_CLK_SEL_SHIFT, CCM_CSCDR2_LPI2C_CLK_SEL_MASK, CCM_NO_BUSY_WAIT), /*!< lpi2c mux name */
|
||||
kCLOCK_LcdifPreMux = CCM_TUPLE(CSCDR2,
|
||||
kCLOCK_Lpi2cMux = CCM_TUPLE(CSCDR2_OFFSET,
|
||||
CCM_CSCDR2_LPI2C_CLK_SEL_SHIFT,
|
||||
CCM_CSCDR2_LPI2C_CLK_SEL_MASK,
|
||||
CCM_NO_BUSY_WAIT), /*!< lpi2c mux name */
|
||||
kCLOCK_LcdifPreMux = CCM_TUPLE(CSCDR2_OFFSET,
|
||||
CCM_CSCDR2_LCDIF_PRE_CLK_SEL_SHIFT,
|
||||
CCM_CSCDR2_LCDIF_PRE_CLK_SEL_MASK,
|
||||
CCM_NO_BUSY_WAIT), /*!< lcdif pre mux name */
|
||||
|
||||
kCLOCK_CsiMux = CCM_TUPLE(
|
||||
CSCDR3, CCM_CSCDR3_CSI_CLK_SEL_SHIFT, CCM_CSCDR3_CSI_CLK_SEL_MASK, CCM_NO_BUSY_WAIT), /*!< csi mux name */
|
||||
kCLOCK_CsiMux = CCM_TUPLE(CSCDR3_OFFSET,
|
||||
CCM_CSCDR3_CSI_CLK_SEL_SHIFT,
|
||||
CCM_CSCDR3_CSI_CLK_SEL_MASK,
|
||||
CCM_NO_BUSY_WAIT), /*!< csi mux name */
|
||||
} clock_mux_t;
|
||||
|
||||
/*!
|
||||
@@ -656,104 +729,130 @@ typedef enum _clock_mux
|
||||
*/
|
||||
typedef enum _clock_div
|
||||
{
|
||||
kCLOCK_ArmDiv = CCM_TUPLE(
|
||||
CACRR, CCM_CACRR_ARM_PODF_SHIFT, CCM_CACRR_ARM_PODF_MASK, CCM_CDHIPR_ARM_PODF_BUSY_SHIFT), /*!< core div name */
|
||||
kCLOCK_ArmDiv = CCM_TUPLE(CACRR_OFFSET,
|
||||
CCM_CACRR_ARM_PODF_SHIFT,
|
||||
CCM_CACRR_ARM_PODF_MASK,
|
||||
CCM_CDHIPR_ARM_PODF_BUSY_SHIFT), /*!< core div name */
|
||||
|
||||
kCLOCK_PeriphClk2Div = CCM_TUPLE(CBCDR,
|
||||
kCLOCK_PeriphClk2Div = CCM_TUPLE(CBCDR_OFFSET,
|
||||
CCM_CBCDR_PERIPH_CLK2_PODF_SHIFT,
|
||||
CCM_CBCDR_PERIPH_CLK2_PODF_MASK,
|
||||
CCM_NO_BUSY_WAIT), /*!< periph clock2 div name */
|
||||
kCLOCK_SemcDiv = CCM_TUPLE(CBCDR,
|
||||
kCLOCK_SemcDiv = CCM_TUPLE(CBCDR_OFFSET,
|
||||
CCM_CBCDR_SEMC_PODF_SHIFT,
|
||||
CCM_CBCDR_SEMC_PODF_MASK,
|
||||
CCM_CDHIPR_SEMC_PODF_BUSY_SHIFT), /*!< semc div name */
|
||||
kCLOCK_AhbDiv = CCM_TUPLE(
|
||||
CBCDR, CCM_CBCDR_AHB_PODF_SHIFT, CCM_CBCDR_AHB_PODF_MASK, CCM_CDHIPR_AHB_PODF_BUSY_SHIFT), /*!< ahb div name */
|
||||
kCLOCK_IpgDiv =
|
||||
CCM_TUPLE(CBCDR, CCM_CBCDR_IPG_PODF_SHIFT, CCM_CBCDR_IPG_PODF_MASK, CCM_NO_BUSY_WAIT), /*!< ipg div name */
|
||||
kCLOCK_AhbDiv = CCM_TUPLE(CBCDR_OFFSET,
|
||||
CCM_CBCDR_AHB_PODF_SHIFT,
|
||||
CCM_CBCDR_AHB_PODF_MASK,
|
||||
CCM_CDHIPR_AHB_PODF_BUSY_SHIFT), /*!< ahb div name */
|
||||
kCLOCK_IpgDiv = CCM_TUPLE(
|
||||
CBCDR_OFFSET, CCM_CBCDR_IPG_PODF_SHIFT, CCM_CBCDR_IPG_PODF_MASK, CCM_NO_BUSY_WAIT), /*!< ipg div name */
|
||||
|
||||
kCLOCK_LpspiDiv = CCM_TUPLE(
|
||||
CBCMR, CCM_CBCMR_LPSPI_PODF_SHIFT, CCM_CBCMR_LPSPI_PODF_MASK, CCM_NO_BUSY_WAIT), /*!< lpspi div name */
|
||||
CBCMR_OFFSET, CCM_CBCMR_LPSPI_PODF_SHIFT, CCM_CBCMR_LPSPI_PODF_MASK, CCM_NO_BUSY_WAIT), /*!< lpspi div name */
|
||||
kCLOCK_LcdifDiv = CCM_TUPLE(
|
||||
CBCMR, CCM_CBCMR_LCDIF_PODF_SHIFT, CCM_CBCMR_LCDIF_PODF_MASK, CCM_NO_BUSY_WAIT), /*!< lcdif div name */
|
||||
CBCMR_OFFSET, CCM_CBCMR_LCDIF_PODF_SHIFT, CCM_CBCMR_LCDIF_PODF_MASK, CCM_NO_BUSY_WAIT), /*!< lcdif div name */
|
||||
|
||||
kCLOCK_FlexspiDiv = CCM_TUPLE(
|
||||
CSCMR1, CCM_CSCMR1_FLEXSPI_PODF_SHIFT, CCM_CSCMR1_FLEXSPI_PODF_MASK, CCM_NO_BUSY_WAIT), /*!< flexspi div name */
|
||||
kCLOCK_PerclkDiv = CCM_TUPLE(
|
||||
CSCMR1, CCM_CSCMR1_PERCLK_PODF_SHIFT, CCM_CSCMR1_PERCLK_PODF_MASK, CCM_NO_BUSY_WAIT), /*!< perclk div name */
|
||||
kCLOCK_FlexspiDiv = CCM_TUPLE(CSCMR1_OFFSET,
|
||||
CCM_CSCMR1_FLEXSPI_PODF_SHIFT,
|
||||
CCM_CSCMR1_FLEXSPI_PODF_MASK,
|
||||
CCM_NO_BUSY_WAIT), /*!< flexspi div name */
|
||||
kCLOCK_PerclkDiv = CCM_TUPLE(CSCMR1_OFFSET,
|
||||
CCM_CSCMR1_PERCLK_PODF_SHIFT,
|
||||
CCM_CSCMR1_PERCLK_PODF_MASK,
|
||||
CCM_NO_BUSY_WAIT), /*!< perclk div name */
|
||||
|
||||
kCLOCK_CanDiv = CCM_TUPLE(
|
||||
CSCMR2, CCM_CSCMR2_CAN_CLK_PODF_SHIFT, CCM_CSCMR2_CAN_CLK_PODF_MASK, CCM_NO_BUSY_WAIT), /*!< can div name */
|
||||
kCLOCK_CanDiv = CCM_TUPLE(CSCMR2_OFFSET,
|
||||
CCM_CSCMR2_CAN_CLK_PODF_SHIFT,
|
||||
CCM_CSCMR2_CAN_CLK_PODF_MASK,
|
||||
CCM_NO_BUSY_WAIT), /*!< can div name */
|
||||
|
||||
kCLOCK_TraceDiv = CCM_TUPLE(
|
||||
CSCDR1, CCM_CSCDR1_TRACE_PODF_SHIFT, CCM_CSCDR1_TRACE_PODF_MASK, CCM_NO_BUSY_WAIT), /*!< trace div name */
|
||||
kCLOCK_Usdhc2Div = CCM_TUPLE(
|
||||
CSCDR1, CCM_CSCDR1_USDHC2_PODF_SHIFT, CCM_CSCDR1_USDHC2_PODF_MASK, CCM_NO_BUSY_WAIT), /*!< usdhc2 div name */
|
||||
kCLOCK_Usdhc1Div = CCM_TUPLE(
|
||||
CSCDR1, CCM_CSCDR1_USDHC1_PODF_SHIFT, CCM_CSCDR1_USDHC1_PODF_MASK, CCM_NO_BUSY_WAIT), /*!< usdhc1 div name */
|
||||
kCLOCK_UartDiv = CCM_TUPLE(
|
||||
CSCDR1, CCM_CSCDR1_UART_CLK_PODF_SHIFT, CCM_CSCDR1_UART_CLK_PODF_MASK, CCM_NO_BUSY_WAIT), /*!< uart div name */
|
||||
kCLOCK_TraceDiv = CCM_TUPLE(CSCDR1_OFFSET,
|
||||
CCM_CSCDR1_TRACE_PODF_SHIFT,
|
||||
CCM_CSCDR1_TRACE_PODF_MASK,
|
||||
CCM_NO_BUSY_WAIT), /*!< trace div name */
|
||||
kCLOCK_Usdhc2Div = CCM_TUPLE(CSCDR1_OFFSET,
|
||||
CCM_CSCDR1_USDHC2_PODF_SHIFT,
|
||||
CCM_CSCDR1_USDHC2_PODF_MASK,
|
||||
CCM_NO_BUSY_WAIT), /*!< usdhc2 div name */
|
||||
kCLOCK_Usdhc1Div = CCM_TUPLE(CSCDR1_OFFSET,
|
||||
CCM_CSCDR1_USDHC1_PODF_SHIFT,
|
||||
CCM_CSCDR1_USDHC1_PODF_MASK,
|
||||
CCM_NO_BUSY_WAIT), /*!< usdhc1 div name */
|
||||
kCLOCK_UartDiv = CCM_TUPLE(CSCDR1_OFFSET,
|
||||
CCM_CSCDR1_UART_CLK_PODF_SHIFT,
|
||||
CCM_CSCDR1_UART_CLK_PODF_MASK,
|
||||
CCM_NO_BUSY_WAIT), /*!< uart div name */
|
||||
|
||||
kCLOCK_Flexio2Div = CCM_TUPLE(CS1CDR,
|
||||
kCLOCK_Flexio2Div = CCM_TUPLE(CS1CDR_OFFSET,
|
||||
CCM_CS1CDR_FLEXIO2_CLK_PODF_SHIFT,
|
||||
CCM_CS1CDR_FLEXIO2_CLK_PODF_MASK,
|
||||
CCM_NO_BUSY_WAIT), /*!< flexio2 pre div name */
|
||||
kCLOCK_Sai3PreDiv = CCM_TUPLE(CS1CDR,
|
||||
kCLOCK_Sai3PreDiv = CCM_TUPLE(CS1CDR_OFFSET,
|
||||
CCM_CS1CDR_SAI3_CLK_PRED_SHIFT,
|
||||
CCM_CS1CDR_SAI3_CLK_PRED_MASK,
|
||||
CCM_NO_BUSY_WAIT), /*!< sai3 pre div name */
|
||||
kCLOCK_Sai3Div = CCM_TUPLE(
|
||||
CS1CDR, CCM_CS1CDR_SAI3_CLK_PODF_SHIFT, CCM_CS1CDR_SAI3_CLK_PODF_MASK, CCM_NO_BUSY_WAIT), /*!< sai3 div name */
|
||||
kCLOCK_Flexio2PreDiv = CCM_TUPLE(CS1CDR,
|
||||
kCLOCK_Sai3Div = CCM_TUPLE(CS1CDR_OFFSET,
|
||||
CCM_CS1CDR_SAI3_CLK_PODF_SHIFT,
|
||||
CCM_CS1CDR_SAI3_CLK_PODF_MASK,
|
||||
CCM_NO_BUSY_WAIT), /*!< sai3 div name */
|
||||
kCLOCK_Flexio2PreDiv = CCM_TUPLE(CS1CDR_OFFSET,
|
||||
CCM_CS1CDR_FLEXIO2_CLK_PRED_SHIFT,
|
||||
CCM_CS1CDR_FLEXIO2_CLK_PRED_MASK,
|
||||
CCM_NO_BUSY_WAIT), /*!< sai3 pre div name */
|
||||
kCLOCK_Sai1PreDiv = CCM_TUPLE(CS1CDR,
|
||||
kCLOCK_Sai1PreDiv = CCM_TUPLE(CS1CDR_OFFSET,
|
||||
CCM_CS1CDR_SAI1_CLK_PRED_SHIFT,
|
||||
CCM_CS1CDR_SAI1_CLK_PRED_MASK,
|
||||
CCM_NO_BUSY_WAIT), /*!< sai1 pre div name */
|
||||
kCLOCK_Sai1Div = CCM_TUPLE(
|
||||
CS1CDR, CCM_CS1CDR_SAI1_CLK_PODF_SHIFT, CCM_CS1CDR_SAI1_CLK_PODF_MASK, CCM_NO_BUSY_WAIT), /*!< sai1 div name */
|
||||
kCLOCK_Sai1Div = CCM_TUPLE(CS1CDR_OFFSET,
|
||||
CCM_CS1CDR_SAI1_CLK_PODF_SHIFT,
|
||||
CCM_CS1CDR_SAI1_CLK_PODF_MASK,
|
||||
CCM_NO_BUSY_WAIT), /*!< sai1 div name */
|
||||
|
||||
kCLOCK_Sai2PreDiv = CCM_TUPLE(CS2CDR,
|
||||
kCLOCK_Sai2PreDiv = CCM_TUPLE(CS2CDR_OFFSET,
|
||||
CCM_CS2CDR_SAI2_CLK_PRED_SHIFT,
|
||||
CCM_CS2CDR_SAI2_CLK_PRED_MASK,
|
||||
CCM_NO_BUSY_WAIT), /*!< sai2 pre div name */
|
||||
kCLOCK_Sai2Div = CCM_TUPLE(
|
||||
CS2CDR, CCM_CS2CDR_SAI2_CLK_PODF_SHIFT, CCM_CS2CDR_SAI2_CLK_PODF_MASK, CCM_NO_BUSY_WAIT), /*!< sai2 div name */
|
||||
kCLOCK_Sai2Div = CCM_TUPLE(CS2CDR_OFFSET,
|
||||
CCM_CS2CDR_SAI2_CLK_PODF_SHIFT,
|
||||
CCM_CS2CDR_SAI2_CLK_PODF_MASK,
|
||||
CCM_NO_BUSY_WAIT), /*!< sai2 div name */
|
||||
|
||||
kCLOCK_Spdif0PreDiv = CCM_TUPLE(CDCDR,
|
||||
kCLOCK_Spdif0PreDiv = CCM_TUPLE(CDCDR_OFFSET,
|
||||
CCM_CDCDR_SPDIF0_CLK_PRED_SHIFT,
|
||||
CCM_CDCDR_SPDIF0_CLK_PRED_MASK,
|
||||
CCM_NO_BUSY_WAIT), /*!< spdif pre div name */
|
||||
kCLOCK_Spdif0Div = CCM_TUPLE(CDCDR,
|
||||
kCLOCK_Spdif0Div = CCM_TUPLE(CDCDR_OFFSET,
|
||||
CCM_CDCDR_SPDIF0_CLK_PODF_SHIFT,
|
||||
CCM_CDCDR_SPDIF0_CLK_PODF_MASK,
|
||||
CCM_NO_BUSY_WAIT), /*!< spdif div name */
|
||||
kCLOCK_Flexio1PreDiv = CCM_TUPLE(CDCDR,
|
||||
kCLOCK_Flexio1PreDiv = CCM_TUPLE(CDCDR_OFFSET,
|
||||
CCM_CDCDR_FLEXIO1_CLK_PRED_SHIFT,
|
||||
CCM_CDCDR_FLEXIO1_CLK_PRED_MASK,
|
||||
CCM_NO_BUSY_WAIT), /*!< flexio1 pre div name */
|
||||
kCLOCK_Flexio1Div = CCM_TUPLE(CDCDR,
|
||||
kCLOCK_Flexio1Div = CCM_TUPLE(CDCDR_OFFSET,
|
||||
CCM_CDCDR_FLEXIO1_CLK_PODF_SHIFT,
|
||||
CCM_CDCDR_FLEXIO1_CLK_PODF_MASK,
|
||||
CCM_NO_BUSY_WAIT), /*!< flexio1 div name */
|
||||
|
||||
kCLOCK_Lpi2cDiv = CCM_TUPLE(CSCDR2,
|
||||
kCLOCK_Lpi2cDiv = CCM_TUPLE(CSCDR2_OFFSET,
|
||||
CCM_CSCDR2_LPI2C_CLK_PODF_SHIFT,
|
||||
CCM_CSCDR2_LPI2C_CLK_PODF_MASK,
|
||||
CCM_NO_BUSY_WAIT), /*!< lpi2c div name */
|
||||
kCLOCK_LcdifPreDiv = CCM_TUPLE(
|
||||
CSCDR2, CCM_CSCDR2_LCDIF_PRED_SHIFT, CCM_CSCDR2_LCDIF_PRED_MASK, CCM_NO_BUSY_WAIT), /*!< lcdif pre div name */
|
||||
kCLOCK_LcdifPreDiv = CCM_TUPLE(CSCDR2_OFFSET,
|
||||
CCM_CSCDR2_LCDIF_PRED_SHIFT,
|
||||
CCM_CSCDR2_LCDIF_PRED_MASK,
|
||||
CCM_NO_BUSY_WAIT), /*!< lcdif pre div name */
|
||||
|
||||
kCLOCK_CsiDiv =
|
||||
CCM_TUPLE(CSCDR3, CCM_CSCDR3_CSI_PODF_SHIFT, CCM_CSCDR3_CSI_PODF_MASK, CCM_NO_BUSY_WAIT), /*!< csi div name */
|
||||
kCLOCK_CsiDiv = CCM_TUPLE(
|
||||
CSCDR3_OFFSET, CCM_CSCDR3_CSI_PODF_SHIFT, CCM_CSCDR3_CSI_PODF_MASK, CCM_NO_BUSY_WAIT), /*!< csi div name */
|
||||
} clock_div_t;
|
||||
|
||||
/*! @brief USB clock source definition. */
|
||||
typedef enum _clock_usb_src
|
||||
{
|
||||
kCLOCK_Usb480M = 0, /*!< Use 480M. */
|
||||
kCLOCK_Usb480M = 0, /*!< Use 480M. */
|
||||
kCLOCK_UsbSrcUnused = (int)0xFFFFFFFFU, /*!< Used when the function does not
|
||||
care the clock source. */
|
||||
} clock_usb_src_t;
|
||||
@@ -768,7 +867,7 @@ typedef enum _clock_usb_phy_src
|
||||
enum _clock_pll_clk_src
|
||||
{
|
||||
kCLOCK_PllClkSrc24M = 0U, /*!< Pll clock source 24M */
|
||||
kCLOCK_PllSrcClkPN = 1U, /*!< Pll clock source CLK1_P and CLK1_N */
|
||||
kCLOCK_PllSrcClkPN = 1U, /*!< Pll clock source CLK1_P and CLK1_N */
|
||||
};
|
||||
|
||||
/*! @brief PLL configuration for ARM */
|
||||
@@ -842,17 +941,17 @@ typedef struct _clock_enet_pll_config
|
||||
/*! @brief PLL name */
|
||||
typedef enum _clock_pll
|
||||
{
|
||||
kCLOCK_PllArm = CCM_ANALOG_TUPLE(PLL_ARM, CCM_ANALOG_PLL_ARM_ENABLE_SHIFT), /*!< PLL ARM */
|
||||
kCLOCK_PllSys = CCM_ANALOG_TUPLE(PLL_SYS, CCM_ANALOG_PLL_SYS_ENABLE_SHIFT), /*!< PLL SYS */
|
||||
kCLOCK_PllUsb1 = CCM_ANALOG_TUPLE(PLL_USB1, CCM_ANALOG_PLL_USB1_ENABLE_SHIFT), /*!< PLL USB1 */
|
||||
kCLOCK_PllAudio = CCM_ANALOG_TUPLE(PLL_AUDIO, CCM_ANALOG_PLL_AUDIO_ENABLE_SHIFT), /*!< PLL Audio */
|
||||
kCLOCK_PllVideo = CCM_ANALOG_TUPLE(PLL_VIDEO, CCM_ANALOG_PLL_VIDEO_ENABLE_SHIFT), /*!< PLL Video */
|
||||
kCLOCK_PllArm = CCM_ANALOG_TUPLE(PLL_ARM_OFFSET, CCM_ANALOG_PLL_ARM_ENABLE_SHIFT), /*!< PLL ARM */
|
||||
kCLOCK_PllSys = CCM_ANALOG_TUPLE(PLL_SYS_OFFSET, CCM_ANALOG_PLL_SYS_ENABLE_SHIFT), /*!< PLL SYS */
|
||||
kCLOCK_PllUsb1 = CCM_ANALOG_TUPLE(PLL_USB1_OFFSET, CCM_ANALOG_PLL_USB1_ENABLE_SHIFT), /*!< PLL USB1 */
|
||||
kCLOCK_PllAudio = CCM_ANALOG_TUPLE(PLL_AUDIO_OFFSET, CCM_ANALOG_PLL_AUDIO_ENABLE_SHIFT), /*!< PLL Audio */
|
||||
kCLOCK_PllVideo = CCM_ANALOG_TUPLE(PLL_VIDEO_OFFSET, CCM_ANALOG_PLL_VIDEO_ENABLE_SHIFT), /*!< PLL Video */
|
||||
|
||||
kCLOCK_PllEnet = CCM_ANALOG_TUPLE(PLL_ENET, CCM_ANALOG_PLL_ENET_ENABLE_SHIFT), /*!< PLL Enet0 */
|
||||
kCLOCK_PllEnet = CCM_ANALOG_TUPLE(PLL_ENET_OFFSET, CCM_ANALOG_PLL_ENET_ENABLE_SHIFT), /*!< PLL Enet0 */
|
||||
|
||||
kCLOCK_PllEnet25M = CCM_ANALOG_TUPLE(PLL_ENET, CCM_ANALOG_PLL_ENET_ENET_25M_REF_EN_SHIFT), /*!< PLL Enet1 */
|
||||
kCLOCK_PllEnet25M = CCM_ANALOG_TUPLE(PLL_ENET_OFFSET, CCM_ANALOG_PLL_ENET_ENET_25M_REF_EN_SHIFT), /*!< PLL Enet1 */
|
||||
|
||||
kCLOCK_PllUsb2 = CCM_ANALOG_TUPLE(PLL_USB2, CCM_ANALOG_PLL_USB2_ENABLE_SHIFT), /*!< PLL USB2 */
|
||||
kCLOCK_PllUsb2 = CCM_ANALOG_TUPLE(PLL_USB2_OFFSET, CCM_ANALOG_PLL_USB2_ENABLE_SHIFT), /*!< PLL USB2 */
|
||||
|
||||
} clock_pll_t;
|
||||
|
||||
@@ -883,7 +982,7 @@ static inline void CLOCK_SetMux(clock_mux_t mux, uint32_t value)
|
||||
{
|
||||
uint32_t busyShift;
|
||||
|
||||
busyShift = CCM_TUPLE_BUSY_SHIFT(mux);
|
||||
busyShift = CCM_TUPLE_BUSY_SHIFT(mux);
|
||||
CCM_TUPLE_REG(CCM, mux) = (CCM_TUPLE_REG(CCM, mux) & (~CCM_TUPLE_MASK(mux))) |
|
||||
(((uint32_t)((value) << CCM_TUPLE_SHIFT(mux))) & CCM_TUPLE_MASK(mux));
|
||||
|
||||
@@ -920,7 +1019,7 @@ static inline void CLOCK_SetDiv(clock_div_t divider, uint32_t value)
|
||||
{
|
||||
uint32_t busyShift;
|
||||
|
||||
busyShift = CCM_TUPLE_BUSY_SHIFT(divider);
|
||||
busyShift = CCM_TUPLE_BUSY_SHIFT(divider);
|
||||
CCM_TUPLE_REG(CCM, divider) = (CCM_TUPLE_REG(CCM, divider) & (~CCM_TUPLE_MASK(divider))) |
|
||||
(((uint32_t)((value) << CCM_TUPLE_SHIFT(divider))) & CCM_TUPLE_MASK(divider));
|
||||
|
||||
@@ -960,7 +1059,7 @@ static inline void CLOCK_ControlGate(clock_ip_name_t name, clock_gate_value_t va
|
||||
|
||||
assert(index <= 6);
|
||||
|
||||
reg = ((volatile uint32_t *)&CCM->CCGR0) + index;
|
||||
reg = ((volatile uint32_t *)&CCM->CCGR0) + index;
|
||||
*reg = ((*reg) & ~(3U << shift)) | (((uint32_t)value) << shift);
|
||||
}
|
||||
|
||||
@@ -1460,6 +1559,16 @@ bool CLOCK_EnableUsbhs1PhyPllClock(clock_usb_phy_src_t src, uint32_t freq);
|
||||
*/
|
||||
void CLOCK_DisableUsbhs1PhyPllClock(void);
|
||||
|
||||
/*!
|
||||
* @brief Use DWT to delay at least for some time.
|
||||
* Please note that, this API will calculate the microsecond period with the maximum
|
||||
* supported CPU frequency, so this API will only delay for at least the given microseconds, if precise
|
||||
* delay count was needed, please implement a new timer count to achieve this function.
|
||||
*
|
||||
* @param delay_us Delay time in unit of microsecond.
|
||||
*/
|
||||
void SDK_DelayAtLeastUs(uint32_t delay_us);
|
||||
|
||||
/* @} */
|
||||
|
||||
#if defined(__cplusplus)
|
||||
|
||||
@@ -7,6 +7,26 @@
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2021 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file fsl_common.c
|
||||
* @brief common drivers
|
||||
* @version 1.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2021.11.11
|
||||
*/
|
||||
|
||||
#include "fsl_common.h"
|
||||
#define SDK_MEM_MAGIC_NUMBER 12345U
|
||||
|
||||
|
||||
@@ -2,10 +2,30 @@
|
||||
* Copyright (c) 2015-2016, Freescale Semiconductor, Inc.
|
||||
* Copyright 2016-2018 NXP
|
||||
* All rights reserved.
|
||||
*
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2021 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file fsl_common.h
|
||||
* @brief common drivers header
|
||||
* @version 1.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2021.11.11
|
||||
*/
|
||||
|
||||
#ifndef _FSL_COMMON_H_
|
||||
#define _FSL_COMMON_H_
|
||||
|
||||
@@ -126,7 +146,7 @@ enum _status_groups
|
||||
kStatusGroup_LPC_I2C_1 = 97, /*!< Group number for LPC_I2C_1 status codes. */
|
||||
kStatusGroup_NOTIFIER = 98, /*!< Group number for NOTIFIER status codes. */
|
||||
kStatusGroup_DebugConsole = 99, /*!< Group number for debug console status codes. */
|
||||
kStatusGroup_SEMC = 100, /*!< Group number for SEMC status codes. */
|
||||
kStatusGroup_SEMC = 100, /*!< Group number for SEMC status codes. */
|
||||
kStatusGroup_ApplicationRangeStart = 101, /*!< Starting number for application groups. */
|
||||
kStatusGroup_IAP = 102, /*!< Group number for IAP status codes */
|
||||
|
||||
@@ -371,7 +391,7 @@ _Pragma("diag_suppress=Pm120")
|
||||
#define AT_QUICKACCESS_SECTION_DATA(func) func
|
||||
#else
|
||||
#error Toolchain not supported.
|
||||
#endif
|
||||
#endif
|
||||
#endif /* __FSL_SDK_DRIVER_QUICK_ACCESS_ENABLE */
|
||||
/* @} */
|
||||
|
||||
@@ -525,7 +545,7 @@ _Pragma("diag_suppress=Pm120")
|
||||
*/
|
||||
uint32_t InstallIRQHandler(IRQn_Type irq, uint32_t irqHandler);
|
||||
#endif /* ENABLE_RAM_VECTOR_TABLE. */
|
||||
|
||||
|
||||
#if (defined(FSL_FEATURE_SOC_SYSCON_COUNT) && (FSL_FEATURE_SOC_SYSCON_COUNT > 0))
|
||||
/*!
|
||||
* @brief Enable specific interrupt for wake-up from deep-sleep mode.
|
||||
@@ -566,15 +586,15 @@ _Pragma("diag_suppress=Pm120")
|
||||
* @param size The length required to malloc.
|
||||
* @param alignbytes The alignment size.
|
||||
* @retval The allocated memory.
|
||||
*/
|
||||
*/
|
||||
void *SDK_Malloc(size_t size, size_t alignbytes);
|
||||
|
||||
|
||||
/*!
|
||||
* @brief Free memory.
|
||||
*
|
||||
* @param ptr The memory to be release.
|
||||
*/
|
||||
void SDK_Free(void *ptr);
|
||||
*/
|
||||
void SDK_Free(void *ptr);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
|
||||
Executable
+1123
File diff suppressed because it is too large
Load Diff
Executable
+213
@@ -0,0 +1,213 @@
|
||||
/*
|
||||
* Copyright (c) 2013 - 2015, Freescale Semiconductor, Inc.
|
||||
* Copyright 2016-2018 NXP
|
||||
* All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*
|
||||
* Debug console shall provide input and output functions to scan and print formatted data.
|
||||
* o Support a format specifier for PRINTF follows this prototype "%[flags][width][.precision][length]specifier"
|
||||
* - [flags] :'-', '+', '#', ' ', '0'
|
||||
* - [width]: number (0,1...)
|
||||
* - [.precision]: number (0,1...)
|
||||
* - [length]: do not support
|
||||
* - [specifier]: 'd', 'i', 'f', 'F', 'x', 'X', 'o', 'p', 'u', 'c', 's', 'n'
|
||||
* o Support a format specifier for SCANF follows this prototype " %[*][width][length]specifier"
|
||||
* - [*]: is supported.
|
||||
* - [width]: number (0,1...)
|
||||
* - [length]: 'h', 'hh', 'l','ll','L'. ignore ('j','z','t')
|
||||
* - [specifier]: 'd', 'i', 'u', 'f', 'F', 'e', 'E', 'g', 'G', 'a', 'A', 'o', 'c', 's'
|
||||
*/
|
||||
|
||||
#ifndef _FSL_DEBUGCONSOLE_H_
|
||||
#define _FSL_DEBUGCONSOLE_H_
|
||||
|
||||
#include "fsl_common.h"
|
||||
//#include "serial_manager.h"
|
||||
|
||||
/*!
|
||||
* @addtogroup debugconsole
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
|
||||
extern serial_handle_t g_serialHandle; /*!< serial manager handle */
|
||||
|
||||
/*! @brief Definition select redirect toolchain printf, scanf to uart or not. */
|
||||
#define DEBUGCONSOLE_REDIRECT_TO_TOOLCHAIN 0U /*!< Select toolchain printf and scanf. */
|
||||
#define DEBUGCONSOLE_REDIRECT_TO_SDK 1U /*!< Select SDK version printf, scanf. */
|
||||
#define DEBUGCONSOLE_DISABLE 2U /*!< Disable debugconsole function. */
|
||||
|
||||
/*! @brief Definition to select sdk or toolchain printf, scanf. The macro only support
|
||||
* to be redefined in project setting.
|
||||
*/
|
||||
#ifndef SDK_DEBUGCONSOLE
|
||||
#define SDK_DEBUGCONSOLE 1U
|
||||
#endif
|
||||
|
||||
/*! @brief Definition to select redirect toolchain printf, scanf to uart or not. */
|
||||
#ifndef SDK_DEBUGCONSOLE_UART
|
||||
/* mcux will handle this macro, not define it here */
|
||||
#if (!defined(__MCUXPRESSO))
|
||||
#define SDK_DEBUGCONSOLE_UART
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(SDK_DEBUGCONSOLE) && !(SDK_DEBUGCONSOLE)
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
/*! @brief Definition to select redirect toolchain printf, scanf to uart or not.
|
||||
*
|
||||
* if SDK_DEBUGCONSOLE defined to 0,it represents select toolchain printf, scanf.
|
||||
* if SDK_DEBUGCONSOLE defined to 1,it represents select SDK version printf, scanf.
|
||||
* if SDK_DEBUGCONSOLE defined to 2,it represents disable debugconsole function.
|
||||
*/
|
||||
#if SDK_DEBUGCONSOLE == DEBUGCONSOLE_DISABLE /* Disable debug console */
|
||||
#define PRINTF
|
||||
#define SCANF
|
||||
#define PUTCHAR
|
||||
#define GETCHAR
|
||||
#elif SDK_DEBUGCONSOLE == DEBUGCONSOLE_REDIRECT_TO_SDK /* Select printf, scanf, putchar, getchar of SDK version. */
|
||||
#define PRINTF DbgConsole_Printf
|
||||
#define SCANF DbgConsole_Scanf
|
||||
#define PUTCHAR DbgConsole_Putchar
|
||||
#define GETCHAR DbgConsole_Getchar
|
||||
#elif SDK_DEBUGCONSOLE == DEBUGCONSOLE_REDIRECT_TO_TOOLCHAIN /* Select printf, scanf, putchar, getchar of toolchain. \ \
|
||||
*/
|
||||
#define PRINTF printf
|
||||
#define SCANF scanf
|
||||
#define PUTCHAR putchar
|
||||
#define GETCHAR getchar
|
||||
#endif /* SDK_DEBUGCONSOLE */
|
||||
|
||||
/*******************************************************************************
|
||||
* Prototypes
|
||||
******************************************************************************/
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/*! @name Initialization*/
|
||||
/* @{ */
|
||||
|
||||
/*!
|
||||
* @brief Initializes the peripheral used for debug messages.
|
||||
*
|
||||
* Call this function to enable debug log messages to be output via the specified peripheral
|
||||
* initialized by the serial manager module.
|
||||
* After this function has returned, stdout and stdin are connected to the selected peripheral.
|
||||
*
|
||||
* @param instance The instance of the module.
|
||||
* @param baudRate The desired baud rate in bits per second.
|
||||
* @param device Low level device type for the debug console, can be one of the following.
|
||||
* @arg kSerialPort_Uart,
|
||||
* @arg kSerialPort_UsbCdc
|
||||
* @arg kSerialPort_UsbCdcVirtual.
|
||||
* @param clkSrcFreq Frequency of peripheral source clock.
|
||||
*
|
||||
* @return Indicates whether initialization was successful or not.
|
||||
* @retval kStatus_Success Execution successfully
|
||||
*/
|
||||
status_t DbgConsole_Init(uint8_t instance, uint32_t baudRate, serial_port_type_t device, uint32_t clkSrcFreq);
|
||||
|
||||
/*!
|
||||
* @brief De-initializes the peripheral used for debug messages.
|
||||
*
|
||||
* Call this function to disable debug log messages to be output via the specified peripheral
|
||||
* initialized by the serial manager module.
|
||||
*
|
||||
* @return Indicates whether de-initialization was successful or not.
|
||||
*/
|
||||
status_t DbgConsole_Deinit(void);
|
||||
|
||||
#if SDK_DEBUGCONSOLE
|
||||
/*!
|
||||
* @brief Writes formatted output to the standard output stream.
|
||||
*
|
||||
* Call this function to write a formatted output to the standard output stream.
|
||||
*
|
||||
* @param formatString Format control string.
|
||||
* @return Returns the number of characters printed or a negative value if an error occurs.
|
||||
*/
|
||||
int DbgConsole_Printf(const char *formatString, ...);
|
||||
|
||||
/*!
|
||||
* @brief Writes a character to stdout.
|
||||
*
|
||||
* Call this function to write a character to stdout.
|
||||
*
|
||||
* @param ch Character to be written.
|
||||
* @return Returns the character written.
|
||||
*/
|
||||
int DbgConsole_Putchar(int ch);
|
||||
|
||||
/*!
|
||||
* @brief Reads formatted data from the standard input stream.
|
||||
*
|
||||
* Call this function to read formatted data from the standard input stream.
|
||||
*
|
||||
* @note Due the limitation in the BM OSA environment (CPU is blocked in the function,
|
||||
* other tasks will not be scheduled), the function cannot be used when the
|
||||
* DEBUG_CONSOLE_TRANSFER_NON_BLOCKING is set in the BM OSA environment.
|
||||
* And an error is returned when the function called in this case. The suggestion
|
||||
* is that polling the non-blocking function DbgConsole_TryGetchar to get the input char.
|
||||
*
|
||||
* @param formatString Format control string.
|
||||
* @return Returns the number of fields successfully converted and assigned.
|
||||
*/
|
||||
int DbgConsole_Scanf(char *formatString, ...);
|
||||
|
||||
/*!
|
||||
* @brief Reads a character from standard input.
|
||||
*
|
||||
* Call this function to read a character from standard input.
|
||||
*
|
||||
* @note Due the limitation in the BM OSA environment (CPU is blocked in the function,
|
||||
* other tasks will not be scheduled), the function cannot be used when the
|
||||
* DEBUG_CONSOLE_TRANSFER_NON_BLOCKING is set in the BM OSA environment.
|
||||
* And an error is returned when the function called in this case. The suggestion
|
||||
* is that polling the non-blocking function DbgConsole_TryGetchar to get the input char.
|
||||
*
|
||||
* @return Returns the character read.
|
||||
*/
|
||||
int DbgConsole_Getchar(void);
|
||||
|
||||
/*!
|
||||
* @brief Debug console flush.
|
||||
*
|
||||
* Call this function to wait the tx buffer empty.
|
||||
* If interrupt transfer is using, make sure the global IRQ is enable before call this function
|
||||
* This function should be called when
|
||||
* 1, before enter power down mode
|
||||
* 2, log is required to print to terminal immediately
|
||||
* @return Indicates whether wait idle was successful or not.
|
||||
*/
|
||||
status_t DbgConsole_Flush(void);
|
||||
|
||||
#ifdef DEBUG_CONSOLE_TRANSFER_NON_BLOCKING
|
||||
/*!
|
||||
* @brief Debug console try to get char
|
||||
* This function provides a API which will not block current task, if character is
|
||||
* available return it, otherwise return fail.
|
||||
* @param ch the address of char to receive
|
||||
* @return Indicates get char was successful or not.
|
||||
*/
|
||||
status_t DbgConsole_TryGetchar(char *ch);
|
||||
#endif
|
||||
|
||||
#endif /* SDK_DEBUGCONSOLE */
|
||||
|
||||
/*! @} */
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/*! @} */
|
||||
|
||||
#endif /* _FSL_DEBUGCONSOLE_H_ */
|
||||
Executable
+158
@@ -0,0 +1,158 @@
|
||||
/*
|
||||
* Copyright 2017 - 2019 NXP
|
||||
* All rights reserved.
|
||||
*
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
#ifndef _FSL_DEBUG_CONSOLE_CONF_H_
|
||||
#define _FSL_DEBUG_CONSOLE_CONF_H_
|
||||
|
||||
/****************Debug console configuration********************/
|
||||
|
||||
/*! @brief If Non-blocking mode is needed, please define it at project setting,
|
||||
* otherwise blocking mode is the default transfer mode.
|
||||
* Warning: If you want to use non-blocking transfer,please make sure the corresponding
|
||||
* IO interrupt is enable, otherwise there is no output.
|
||||
* And non-blocking is combine with buffer, no matter bare-metal or rtos.
|
||||
* Below shows how to configure in your project if you want to use non-blocking mode.
|
||||
* For IAR, right click project and select "Options", define it in "C/C++ Compiler->Preprocessor->Defined symbols".
|
||||
* For KEIL, click "Options for Target…", define it in "C/C++->Preprocessor Symbols->Define".
|
||||
* For ARMGCC, open CmakeLists.txt and add the following lines,
|
||||
* "SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -DDEBUG_CONSOLE_TRANSFER_NON_BLOCKING")" for debug target.
|
||||
* "SET(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -DDEBUG_CONSOLE_TRANSFER_NON_BLOCKING")" for release target.
|
||||
* For MCUxpresso, right click project and select "Properties", define it in "C/C++ Build->Settings->MCU C
|
||||
* Complier->Preprocessor".
|
||||
*
|
||||
*/
|
||||
#ifdef DEBUG_CONSOLE_TRANSFER_NON_BLOCKING
|
||||
/*! @brief define the transmit buffer length which is used to store the multi task log, buffer is enabled automatically
|
||||
* when
|
||||
* non-blocking transfer is using,
|
||||
* This value will affect the RAM's ultilization, should be set per paltform's capability and software requirement.
|
||||
* If it is configured too small, log maybe missed , because the log will not be
|
||||
* buffered if the buffer is full, and the print will return immediately with -1.
|
||||
* And this value should be multiple of 4 to meet memory alignment.
|
||||
*
|
||||
*/
|
||||
#ifndef DEBUG_CONSOLE_TRANSMIT_BUFFER_LEN
|
||||
#define DEBUG_CONSOLE_TRANSMIT_BUFFER_LEN (512U)
|
||||
#endif /* DEBUG_CONSOLE_TRANSMIT_BUFFER_LEN */
|
||||
|
||||
/*! @brief define the receive buffer length which is used to store the user input, buffer is enabled automatically when
|
||||
* non-blocking transfer is using,
|
||||
* This value will affect the RAM's ultilization, should be set per paltform's capability and software requirement.
|
||||
* If it is configured too small, log maybe missed, because buffer will be overwrited if buffer is too small.
|
||||
* And this value should be multiple of 4 to meet memory alignment.
|
||||
*
|
||||
*/
|
||||
#ifndef DEBUG_CONSOLE_RECEIVE_BUFFER_LEN
|
||||
#define DEBUG_CONSOLE_RECEIVE_BUFFER_LEN (1024U)
|
||||
#endif /* DEBUG_CONSOLE_RECEIVE_BUFFER_LEN */
|
||||
|
||||
/*!@ brief Whether enable the reliable TX function
|
||||
* If the macro is zero, the reliable TX function of the debug console is disabled.
|
||||
* When the macro is zero, the string of PRINTF will be thrown away after the transmit buffer is full.
|
||||
*/
|
||||
#ifndef DEBUG_CONSOLE_TX_RELIABLE_ENABLE
|
||||
#define DEBUG_CONSOLE_TX_RELIABLE_ENABLE (1U)
|
||||
#endif /* DEBUG_CONSOLE_RX_ENABLE */
|
||||
|
||||
#else
|
||||
#define DEBUG_CONSOLE_TRANSFER_BLOCKING
|
||||
#endif /* DEBUG_CONSOLE_TRANSFER_NON_BLOCKING */
|
||||
|
||||
/*!@ brief Whether enable the RX function
|
||||
* If the macro is zero, the receive function of the debug console is disabled.
|
||||
*/
|
||||
#ifndef DEBUG_CONSOLE_RX_ENABLE
|
||||
#define DEBUG_CONSOLE_RX_ENABLE (1U)
|
||||
#endif /* DEBUG_CONSOLE_RX_ENABLE */
|
||||
|
||||
/*!@ brief define the MAX log length debug console support , that is when you call printf("log", x);, the log
|
||||
* length can not bigger than this value.
|
||||
* This macro decide the local log buffer length, the buffer locate at stack, the stack maybe overflow if
|
||||
* the buffer is too big and current task stack size not big enough.
|
||||
*/
|
||||
#ifndef DEBUG_CONSOLE_PRINTF_MAX_LOG_LEN
|
||||
#define DEBUG_CONSOLE_PRINTF_MAX_LOG_LEN (128U)
|
||||
#endif /* DEBUG_CONSOLE_PRINTF_MAX_LOG_LEN */
|
||||
|
||||
/*!@ brief define the buffer support buffer scanf log length, that is when you call scanf("log", &x);, the log
|
||||
* length can not bigger than this value.
|
||||
* As same as the DEBUG_CONSOLE_BUFFER_PRINTF_MAX_LOG_LEN.
|
||||
*/
|
||||
#ifndef DEBUG_CONSOLE_SCANF_MAX_LOG_LEN
|
||||
#define DEBUG_CONSOLE_SCANF_MAX_LOG_LEN (20U)
|
||||
#endif /* DEBUG_CONSOLE_SCANF_MAX_LOG_LEN */
|
||||
|
||||
/*! @brief Debug console synchronization
|
||||
* User should not change these macro for synchronization mode, but add the
|
||||
* corresponding synchronization mechanism per different software environment.
|
||||
* Such as, if another RTOS is used,
|
||||
* add:
|
||||
* #define DEBUG_CONSOLE_SYNCHRONIZATION_XXXX 3
|
||||
* in this configuration file and implement the synchronization in fsl.log.c.
|
||||
*/
|
||||
/*! @brief synchronization for baremetal software */
|
||||
#define DEBUG_CONSOLE_SYNCHRONIZATION_BM 0
|
||||
/*! @brief synchronization for freertos software */
|
||||
#define DEBUG_CONSOLE_SYNCHRONIZATION_FREERTOS 1
|
||||
|
||||
/*! @brief RTOS synchronization mechanism disable
|
||||
* If not defined, default is enable, to avoid multitask log print mess.
|
||||
* If other RTOS is used, you can implement the RTOS's specific synchronization mechanism in fsl.log.c
|
||||
* If synchronization is disabled, log maybe messed on terminal.
|
||||
*/
|
||||
#ifndef DEBUG_CONSOLE_DISABLE_RTOS_SYNCHRONIZATION
|
||||
#ifdef DEBUG_CONSOLE_TRANSFER_NON_BLOCKING
|
||||
#ifdef FSL_RTOS_FREE_RTOS
|
||||
#define DEBUG_CONSOLE_SYNCHRONIZATION_MODE DEBUG_CONSOLE_SYNCHRONIZATION_FREERTOS
|
||||
#else
|
||||
#define DEBUG_CONSOLE_SYNCHRONIZATION_MODE DEBUG_CONSOLE_SYNCHRONIZATION_BM
|
||||
#endif /* FSL_RTOS_FREE_RTOS */
|
||||
#else
|
||||
#define DEBUG_CONSOLE_SYNCHRONIZATION_MODE DEBUG_CONSOLE_SYNCHRONIZATION_BM
|
||||
#endif /* DEBUG_CONSOLE_TRANSFER_NON_BLOCKING */
|
||||
#endif /* DEBUG_CONSOLE_DISABLE_RTOS_SYNCHRONIZATION */
|
||||
|
||||
/*! @brief echo function support
|
||||
* If you want to use the echo function,please define DEBUG_CONSOLE_ENABLE_ECHO
|
||||
* at your project setting.
|
||||
*/
|
||||
#ifndef DEBUG_CONSOLE_ENABLE_ECHO
|
||||
#define DEBUG_CONSOLE_ENABLE_ECHO_FUNCTION 0
|
||||
#else
|
||||
#define DEBUG_CONSOLE_ENABLE_ECHO_FUNCTION 1
|
||||
#endif /* DEBUG_CONSOLE_ENABLE_ECHO */
|
||||
|
||||
/*********************************************************************/
|
||||
|
||||
/***************Debug console other configuration*********************/
|
||||
/*! @brief Definition to printf the float number. */
|
||||
#ifndef PRINTF_FLOAT_ENABLE
|
||||
#define PRINTF_FLOAT_ENABLE 0U
|
||||
#endif /* PRINTF_FLOAT_ENABLE */
|
||||
|
||||
/*! @brief Definition to scanf the float number. */
|
||||
#ifndef SCANF_FLOAT_ENABLE
|
||||
#define SCANF_FLOAT_ENABLE 0U
|
||||
#endif /* SCANF_FLOAT_ENABLE */
|
||||
|
||||
/*! @brief Definition to support advanced format specifier for printf. */
|
||||
#ifndef PRINTF_ADVANCED_ENABLE
|
||||
#define PRINTF_ADVANCED_ENABLE 0U
|
||||
#endif /* PRINTF_ADVANCED_ENABLE */
|
||||
|
||||
/*! @brief Definition to support advanced format specifier for scanf. */
|
||||
#ifndef SCANF_ADVANCED_ENABLE
|
||||
#define SCANF_ADVANCED_ENABLE 0U
|
||||
#endif /* SCANF_ADVANCED_ENABLE */
|
||||
|
||||
/*! @brief Definition to select virtual com(USB CDC) as the debug console. */
|
||||
#ifndef BOARD_USE_VIRTUALCOM
|
||||
#define BOARD_USE_VIRTUALCOM 0U
|
||||
#endif
|
||||
/*******************************************************************/
|
||||
|
||||
#endif /* _FSL_DEBUG_CONSOLE_CONF_H_ */
|
||||
+3517
File diff suppressed because it is too large
Load Diff
+1629
File diff suppressed because it is too large
Load Diff
+171
@@ -0,0 +1,171 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Freescale Semiconductor, Inc.
|
||||
* Copyright 2016-2017 NXP
|
||||
* All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include "fsl_gpio.h"
|
||||
|
||||
/* Component ID definition, used by tools. */
|
||||
#ifndef FSL_COMPONENT_ID
|
||||
#define FSL_COMPONENT_ID "platform.drivers.igpio"
|
||||
#endif
|
||||
|
||||
/*******************************************************************************
|
||||
* Variables
|
||||
******************************************************************************/
|
||||
|
||||
/* Array of GPIO peripheral base address. */
|
||||
static GPIO_Type *const s_gpioBases[] = GPIO_BASE_PTRS;
|
||||
|
||||
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
|
||||
/* Array of GPIO clock name. */
|
||||
static const clock_ip_name_t s_gpioClock[] = GPIO_CLOCKS;
|
||||
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
|
||||
|
||||
/*******************************************************************************
|
||||
* Prototypes
|
||||
******************************************************************************/
|
||||
|
||||
/*!
|
||||
* @brief Gets the GPIO instance according to the GPIO base
|
||||
*
|
||||
* @param base GPIO peripheral base pointer(PTA, PTB, PTC, etc.)
|
||||
* @retval GPIO instance
|
||||
*/
|
||||
static uint32_t GPIO_GetInstance(GPIO_Type *base);
|
||||
|
||||
/*******************************************************************************
|
||||
* Code
|
||||
******************************************************************************/
|
||||
|
||||
static uint32_t GPIO_GetInstance(GPIO_Type *base)
|
||||
{
|
||||
uint32_t instance;
|
||||
|
||||
/* Find the instance index from base address mappings. */
|
||||
for (instance = 0; instance < ARRAY_SIZE(s_gpioBases); instance++)
|
||||
{
|
||||
if (s_gpioBases[instance] == base)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
assert(instance < ARRAY_SIZE(s_gpioBases));
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
/*!
|
||||
* brief Initializes the GPIO peripheral according to the specified
|
||||
* parameters in the initConfig.
|
||||
*
|
||||
* param base GPIO base pointer.
|
||||
* param pin Specifies the pin number
|
||||
* param initConfig pointer to a ref gpio_pin_config_t structure that
|
||||
* contains the configuration information.
|
||||
*/
|
||||
void GPIO_PinInit(GPIO_Type *base, uint32_t pin, const gpio_pin_config_t *Config)
|
||||
{
|
||||
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
|
||||
/* Enable GPIO clock. */
|
||||
uint32_t instance = GPIO_GetInstance(base);
|
||||
|
||||
/* If The clock IP is valid, enable the clock gate. */
|
||||
if ((instance < ARRAY_SIZE(s_gpioClock)) && (kCLOCK_IpInvalid != s_gpioClock[instance]))
|
||||
{
|
||||
CLOCK_EnableClock(s_gpioClock[instance]);
|
||||
}
|
||||
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
|
||||
|
||||
/* Register reset to default value */
|
||||
base->IMR &= ~(1U << pin);
|
||||
|
||||
/* Configure GPIO pin direction */
|
||||
if (Config->direction == kGPIO_DigitalInput)
|
||||
{
|
||||
base->GDIR &= ~(1U << pin);
|
||||
}
|
||||
else
|
||||
{
|
||||
GPIO_PinWrite(base, pin, Config->outputLogic);
|
||||
base->GDIR |= (1U << pin);
|
||||
}
|
||||
|
||||
/* Configure GPIO pin interrupt mode */
|
||||
GPIO_SetPinInterruptConfig(base, pin, Config->interruptMode);
|
||||
}
|
||||
|
||||
/*!
|
||||
* brief Sets the output level of the individual GPIO pin to logic 1 or 0.
|
||||
*
|
||||
* param base GPIO base pointer.
|
||||
* param pin GPIO port pin number.
|
||||
* param output GPIOpin output logic level.
|
||||
* - 0: corresponding pin output low-logic level.
|
||||
* - 1: corresponding pin output high-logic level.
|
||||
*/
|
||||
void GPIO_PinWrite(GPIO_Type *base, uint32_t pin, uint8_t output)
|
||||
{
|
||||
assert(pin < 32);
|
||||
if (output == 0U)
|
||||
{
|
||||
base->DR &= ~(1U << pin); /* Set pin output to low level.*/
|
||||
}
|
||||
else
|
||||
{
|
||||
base->DR |= (1U << pin); /* Set pin output to high level.*/
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* brief Sets the current pin interrupt mode.
|
||||
*
|
||||
* param base GPIO base pointer.
|
||||
* param pin GPIO port pin number.
|
||||
* param pininterruptMode pointer to a ref gpio_interrupt_mode_t structure
|
||||
* that contains the interrupt mode information.
|
||||
*/
|
||||
void GPIO_PinSetInterruptConfig(GPIO_Type *base, uint32_t pin, gpio_interrupt_mode_t pinInterruptMode)
|
||||
{
|
||||
volatile uint32_t *icr;
|
||||
uint32_t icrShift;
|
||||
|
||||
icrShift = pin;
|
||||
|
||||
/* Register reset to default value */
|
||||
base->EDGE_SEL &= ~(1U << pin);
|
||||
|
||||
if (pin < 16)
|
||||
{
|
||||
icr = &(base->ICR1);
|
||||
}
|
||||
else
|
||||
{
|
||||
icr = &(base->ICR2);
|
||||
icrShift -= 16;
|
||||
}
|
||||
switch (pinInterruptMode)
|
||||
{
|
||||
case (kGPIO_IntLowLevel):
|
||||
*icr &= ~(3U << (2 * icrShift));
|
||||
break;
|
||||
case (kGPIO_IntHighLevel):
|
||||
*icr = (*icr & (~(3U << (2 * icrShift)))) | (1U << (2 * icrShift));
|
||||
break;
|
||||
case (kGPIO_IntRisingEdge):
|
||||
*icr = (*icr & (~(3U << (2 * icrShift)))) | (2U << (2 * icrShift));
|
||||
break;
|
||||
case (kGPIO_IntFallingEdge):
|
||||
*icr |= (3U << (2 * icrShift));
|
||||
break;
|
||||
case (kGPIO_IntRisingOrFallingEdge):
|
||||
base->EDGE_SEL |= (1U << pin);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -6,6 +6,26 @@
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2021 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file fsl_iomuxc.h
|
||||
* @brief io mux drivers
|
||||
* @version 1.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2021.11.11
|
||||
*/
|
||||
|
||||
#ifndef _FSL_IOMUXC_H_
|
||||
#define _FSL_IOMUXC_H_
|
||||
|
||||
|
||||
@@ -6,6 +6,26 @@
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2021 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file fsl_lpuart.c
|
||||
* @brief fsl uart drivers
|
||||
* @version 1.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2021.11.11
|
||||
*/
|
||||
|
||||
#include "fsl_lpuart.h"
|
||||
|
||||
/*******************************************************************************
|
||||
|
||||
@@ -5,6 +5,27 @@
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2021 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file fsl_lpuart.h
|
||||
* @brief fsl uart drivers
|
||||
* @version 1.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2021.11.11
|
||||
*/
|
||||
|
||||
#ifndef _FSL_LPUART_H_
|
||||
#define _FSL_LPUART_H_
|
||||
|
||||
|
||||
+336
@@ -0,0 +1,336 @@
|
||||
/*
|
||||
* Copyright (c) 2015, Freescale Semiconductor, Inc.
|
||||
* Copyright 2016-2018 NXP
|
||||
* All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2021 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file fsl_phy.c
|
||||
* @brief phy drivers for ksz8081
|
||||
* @version 1.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2021.11.11
|
||||
*/
|
||||
|
||||
#include "lwipopts.h"
|
||||
#include "fsl_phy.h"
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
|
||||
/*! @brief Defines the timeout macro. */
|
||||
#define PHY_TIMEOUT_COUNT 100000
|
||||
|
||||
/*******************************************************************************
|
||||
* Prototypes
|
||||
******************************************************************************/
|
||||
|
||||
/*!
|
||||
* @brief Get the ENET instance from peripheral base address.
|
||||
*
|
||||
* @param base ENET peripheral base address.
|
||||
* @return ENET instance.
|
||||
*/
|
||||
extern uint32_t ENET_GetInstance(ENET_Type *base);
|
||||
|
||||
/*******************************************************************************
|
||||
* Variables
|
||||
******************************************************************************/
|
||||
|
||||
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
|
||||
/*! @brief Pointers to enet clocks for each instance. */
|
||||
extern clock_ip_name_t s_enetClock[FSL_FEATURE_SOC_ENET_COUNT];
|
||||
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
|
||||
|
||||
/*******************************************************************************
|
||||
* Code
|
||||
******************************************************************************/
|
||||
|
||||
status_t PHY_Init(ENET_Type *base, uint32_t phyAddr, uint32_t srcClock_Hz)
|
||||
{
|
||||
uint32_t bssReg;
|
||||
uint32_t counter = PHY_TIMEOUT_COUNT;
|
||||
uint32_t idReg = 0;
|
||||
status_t result = kStatus_Success;
|
||||
uint32_t instance = ENET_GetInstance(base);
|
||||
uint32_t timeDelay;
|
||||
uint32_t ctlReg = 0;
|
||||
|
||||
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
|
||||
/* Set SMI first. */
|
||||
CLOCK_EnableClock(s_enetClock[instance]);
|
||||
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
|
||||
ENET_SetSMI(base, srcClock_Hz, false);
|
||||
|
||||
/* Initialization after PHY stars to work. */
|
||||
while ((idReg != PHY_CONTROL_ID1) && (counter != 0))
|
||||
{
|
||||
PHY_Read(base, phyAddr, PHY_ID1_REG, &idReg);
|
||||
counter--;
|
||||
}
|
||||
|
||||
if (!counter)
|
||||
{
|
||||
return kStatus_Fail;
|
||||
}
|
||||
|
||||
/* Reset PHY. */
|
||||
counter = PHY_TIMEOUT_COUNT;
|
||||
result = PHY_Write(base, phyAddr, PHY_BASICCONTROL_REG, PHY_BCTL_RESET_MASK);
|
||||
if (result == kStatus_Success)
|
||||
{
|
||||
#if defined(FSL_FEATURE_PHYKSZ8081_USE_RMII50M_MODE)
|
||||
uint32_t data = 0;
|
||||
result = PHY_Read(base, phyAddr, PHY_CONTROL2_REG, &data);
|
||||
if (result != kStatus_Success)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
result = PHY_Write(base, phyAddr, PHY_CONTROL2_REG, (data | PHY_CTL2_REFCLK_SELECT_MASK));
|
||||
if (result != kStatus_Success)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
#endif /* FSL_FEATURE_PHYKSZ8081_USE_RMII50M_MODE */
|
||||
|
||||
/* Set the negotiation. */
|
||||
result = PHY_Write(base, phyAddr, PHY_AUTONEG_ADVERTISE_REG,
|
||||
(PHY_100BASETX_FULLDUPLEX_MASK | PHY_100BASETX_HALFDUPLEX_MASK |
|
||||
PHY_10BASETX_FULLDUPLEX_MASK | PHY_10BASETX_HALFDUPLEX_MASK | 0x1U));
|
||||
if (result == kStatus_Success)
|
||||
{
|
||||
result =
|
||||
PHY_Write(base, phyAddr, PHY_BASICCONTROL_REG, (PHY_BCTL_AUTONEG_MASK | PHY_BCTL_RESTART_AUTONEG_MASK));
|
||||
if (result == kStatus_Success)
|
||||
{
|
||||
/* Check auto negotiation complete. */
|
||||
while (counter--)
|
||||
{
|
||||
result = PHY_Read(base, phyAddr, PHY_BASICSTATUS_REG, &bssReg);
|
||||
if (result == kStatus_Success)
|
||||
{
|
||||
PHY_Read(base, phyAddr, PHY_CONTROL1_REG, &ctlReg);
|
||||
if (((bssReg & PHY_BSTATUS_AUTONEGCOMP_MASK) != 0) && (ctlReg & PHY_LINK_READY_MASK))
|
||||
{
|
||||
/* Wait a moment for Phy status stable. */
|
||||
for (timeDelay = 0; timeDelay < PHY_TIMEOUT_COUNT; timeDelay++)
|
||||
{
|
||||
__ASM("nop");
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!counter)
|
||||
{
|
||||
return kStatus_PHY_AutoNegotiateFail;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
status_t PHY_Write(ENET_Type *base, uint32_t phyAddr, uint32_t phyReg, uint32_t data)
|
||||
{
|
||||
uint32_t counter;
|
||||
|
||||
/* Clear the SMI interrupt event. */
|
||||
ENET_ClearInterruptStatus(base, ENET_EIR_MII_MASK);
|
||||
|
||||
/* Starts a SMI write command. */
|
||||
ENET_StartSMIWrite(base, phyAddr, phyReg, kENET_MiiWriteValidFrame, data);
|
||||
|
||||
/* Wait for SMI complete. */
|
||||
for (counter = PHY_TIMEOUT_COUNT; counter > 0; counter--)
|
||||
{
|
||||
if (ENET_GetInterruptStatus(base) & ENET_EIR_MII_MASK)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check for timeout. */
|
||||
if (!counter)
|
||||
{
|
||||
return kStatus_PHY_SMIVisitTimeout;
|
||||
}
|
||||
|
||||
/* Clear MII interrupt event. */
|
||||
ENET_ClearInterruptStatus(base, ENET_EIR_MII_MASK);
|
||||
|
||||
return kStatus_Success;
|
||||
}
|
||||
|
||||
status_t PHY_Read(ENET_Type *base, uint32_t phyAddr, uint32_t phyReg, uint32_t *dataPtr)
|
||||
{
|
||||
assert(dataPtr);
|
||||
|
||||
uint32_t counter;
|
||||
|
||||
/* Clear the MII interrupt event. */
|
||||
ENET_ClearInterruptStatus(base, ENET_EIR_MII_MASK);
|
||||
|
||||
/* Starts a SMI read command operation. */
|
||||
ENET_StartSMIRead(base, phyAddr, phyReg, kENET_MiiReadValidFrame);
|
||||
|
||||
/* Wait for MII complete. */
|
||||
for (counter = PHY_TIMEOUT_COUNT; counter > 0; counter--)
|
||||
{
|
||||
if (ENET_GetInterruptStatus(base) & ENET_EIR_MII_MASK)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check for timeout. */
|
||||
if (!counter)
|
||||
{
|
||||
return kStatus_PHY_SMIVisitTimeout;
|
||||
}
|
||||
|
||||
/* Get data from MII register. */
|
||||
*dataPtr = ENET_ReadSMIData(base);
|
||||
|
||||
/* Clear MII interrupt event. */
|
||||
ENET_ClearInterruptStatus(base, ENET_EIR_MII_MASK);
|
||||
|
||||
return kStatus_Success;
|
||||
}
|
||||
|
||||
status_t PHY_EnableLoopback(ENET_Type *base, uint32_t phyAddr, phy_loop_t mode, phy_speed_t speed, bool enable)
|
||||
{
|
||||
status_t result;
|
||||
uint32_t data = 0;
|
||||
|
||||
/* Set the loop mode. */
|
||||
if (enable)
|
||||
{
|
||||
if (mode == kPHY_LocalLoop)
|
||||
{
|
||||
if (speed == kPHY_Speed100M)
|
||||
{
|
||||
data = PHY_BCTL_SPEED_100M_MASK | PHY_BCTL_DUPLEX_MASK | PHY_BCTL_LOOP_MASK;
|
||||
}
|
||||
else
|
||||
{
|
||||
data = PHY_BCTL_DUPLEX_MASK | PHY_BCTL_LOOP_MASK;
|
||||
}
|
||||
return PHY_Write(base, phyAddr, PHY_BASICCONTROL_REG, data);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* First read the current status in control register. */
|
||||
result = PHY_Read(base, phyAddr, PHY_CONTROL2_REG, &data);
|
||||
if (result == kStatus_Success)
|
||||
{
|
||||
return PHY_Write(base, phyAddr, PHY_CONTROL2_REG, (data | PHY_CTL2_REMOTELOOP_MASK));
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Disable the loop mode. */
|
||||
if (mode == kPHY_LocalLoop)
|
||||
{
|
||||
/* First read the current status in control register. */
|
||||
result = PHY_Read(base, phyAddr, PHY_BASICCONTROL_REG, &data);
|
||||
if (result == kStatus_Success)
|
||||
{
|
||||
data &= ~PHY_BCTL_LOOP_MASK;
|
||||
return PHY_Write(base, phyAddr, PHY_BASICCONTROL_REG, (data | PHY_BCTL_RESTART_AUTONEG_MASK));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* First read the current status in control one register. */
|
||||
result = PHY_Read(base, phyAddr, PHY_CONTROL2_REG, &data);
|
||||
if (result == kStatus_Success)
|
||||
{
|
||||
return PHY_Write(base, phyAddr, PHY_CONTROL2_REG, (data & ~PHY_CTL2_REMOTELOOP_MASK));
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
status_t PHY_GetLinkStatus(ENET_Type *base, uint32_t phyAddr, bool *status)
|
||||
{
|
||||
assert(status);
|
||||
|
||||
status_t result = kStatus_Success;
|
||||
uint32_t data;
|
||||
|
||||
/* Read the basic status register. */
|
||||
result = PHY_Read(base, phyAddr, PHY_BASICSTATUS_REG, &data);
|
||||
if (result == kStatus_Success)
|
||||
{
|
||||
if (!(PHY_BSTATUS_LINKSTATUS_MASK & data))
|
||||
{
|
||||
/* link down. */
|
||||
*status = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* link up. */
|
||||
*status = true;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
status_t PHY_GetLinkSpeedDuplex(ENET_Type *base, uint32_t phyAddr, phy_speed_t *speed, phy_duplex_t *duplex)
|
||||
{
|
||||
assert(duplex);
|
||||
|
||||
status_t result = kStatus_Success;
|
||||
uint32_t data, ctlReg;
|
||||
|
||||
|
||||
/* Read the control two register. */
|
||||
result = PHY_Read(base, phyAddr, PHY_CONTROL1_REG, &ctlReg);
|
||||
if (result == kStatus_Success)
|
||||
{
|
||||
data = ctlReg & PHY_CTL1_SPEEDUPLX_MASK;
|
||||
if ((PHY_CTL1_10FULLDUPLEX_MASK == data) || (PHY_CTL1_100FULLDUPLEX_MASK == data))
|
||||
{
|
||||
/* Full duplex. */
|
||||
*duplex = kPHY_FullDuplex;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Half duplex. */
|
||||
*duplex = kPHY_HalfDuplex;
|
||||
}
|
||||
|
||||
data = ctlReg & PHY_CTL1_SPEEDUPLX_MASK;
|
||||
if ((PHY_CTL1_100HALFDUPLEX_MASK == data) || (PHY_CTL1_100FULLDUPLEX_MASK == data))
|
||||
{
|
||||
/* 100M speed. */
|
||||
*speed = kPHY_Speed100M;
|
||||
}
|
||||
else
|
||||
{ /* 10M speed. */
|
||||
*speed = kPHY_Speed10M;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
+221
@@ -0,0 +1,221 @@
|
||||
/*
|
||||
* Copyright (c) 2015, Freescale Semiconductor, Inc.
|
||||
* Copyright 2016-2017 NXP
|
||||
* All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2021 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file fsl_phy.h
|
||||
* @brief phy drivers for ksz8081
|
||||
* @version 1.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2021.11.11
|
||||
*/
|
||||
|
||||
#ifndef _FSL_PHY_H_
|
||||
#define _FSL_PHY_H_
|
||||
|
||||
#include "fsl_enet.h"
|
||||
|
||||
/*!
|
||||
* @addtogroup phy_driver
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
|
||||
/*! @brief PHY driver version */
|
||||
#define FSL_PHY_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) /*!< Version 2.0.0. */
|
||||
|
||||
/*! @brief Defines the PHY registers. */
|
||||
#define PHY_BASICCONTROL_REG 0x00U /*!< The PHY basic control register. */
|
||||
#define PHY_BASICSTATUS_REG 0x01U /*!< The PHY basic status register. */
|
||||
#define PHY_ID1_REG 0x02U /*!< The PHY ID one register. */
|
||||
#define PHY_ID2_REG 0x03U /*!< The PHY ID two register. */
|
||||
#define PHY_AUTONEG_ADVERTISE_REG 0x04U /*!< The PHY auto-negotiate advertise register. */
|
||||
#define PHY_CONTROL1_REG 0x1EU /*!< The PHY control one register. */
|
||||
#define PHY_CONTROL2_REG 0x1FU /*!< The PHY control two register. */
|
||||
|
||||
#define PHY_CONTROL_ID1 0x22U /*!< The PHY ID1*/
|
||||
|
||||
/*! @brief Defines the mask flag in basic control register. */
|
||||
#define PHY_BCTL_DUPLEX_MASK 0x0100U /*!< The PHY duplex bit mask. */
|
||||
#define PHY_BCTL_RESTART_AUTONEG_MASK 0x0200U /*!< The PHY restart auto negotiation mask. */
|
||||
#define PHY_BCTL_AUTONEG_MASK 0x1000U /*!< The PHY auto negotiation bit mask. */
|
||||
#define PHY_BCTL_SPEED_MASK 0x2000U /*!< The PHY speed bit mask. */
|
||||
#define PHY_BCTL_LOOP_MASK 0x4000U /*!< The PHY loop bit mask. */
|
||||
#define PHY_BCTL_RESET_MASK 0x8000U /*!< The PHY reset bit mask. */
|
||||
#define PHY_BCTL_SPEED_100M_MASK 0x2000U /*!< The PHY 100M speed mask. */
|
||||
|
||||
/*!@brief Defines the mask flag of operation mode in control two register*/
|
||||
#define PHY_CTL2_REMOTELOOP_MASK 0x0004U /*!< The PHY remote loopback mask. */
|
||||
#define PHY_CTL2_REFCLK_SELECT_MASK 0x0080U /*!< The PHY RMII reference clock select. */
|
||||
#define PHY_CTL1_10HALFDUPLEX_MASK 0x0001U /*!< The PHY 10M half duplex mask. */
|
||||
#define PHY_CTL1_100HALFDUPLEX_MASK 0x0002U /*!< The PHY 100M half duplex mask. */
|
||||
#define PHY_CTL1_10FULLDUPLEX_MASK 0x0005U /*!< The PHY 10M full duplex mask. */
|
||||
#define PHY_CTL1_100FULLDUPLEX_MASK 0x0006U /*!< The PHY 100M full duplex mask. */
|
||||
#define PHY_CTL1_SPEEDUPLX_MASK 0x0007U /*!< The PHY speed and duplex mask. */
|
||||
#define PHY_CTL1_ENERGYDETECT_MASK 0x10U /*!< The PHY signal present on rx differential pair. */
|
||||
#define PHY_CTL1_LINKUP_MASK 0x100U /*!< The PHY link up. */
|
||||
#define PHY_LINK_READY_MASK (PHY_CTL1_ENERGYDETECT_MASK | PHY_CTL1_LINKUP_MASK)
|
||||
|
||||
/*! @brief Defines the mask flag in basic status register. */
|
||||
#define PHY_BSTATUS_LINKSTATUS_MASK 0x0004U /*!< The PHY link status mask. */
|
||||
#define PHY_BSTATUS_AUTONEGABLE_MASK 0x0008U /*!< The PHY auto-negotiation ability mask. */
|
||||
#define PHY_BSTATUS_AUTONEGCOMP_MASK 0x0020U /*!< The PHY auto-negotiation complete mask. */
|
||||
|
||||
/*! @brief Defines the mask flag in PHY auto-negotiation advertise register. */
|
||||
#define PHY_100BaseT4_ABILITY_MASK 0x200U /*!< The PHY have the T4 ability. */
|
||||
#define PHY_100BASETX_FULLDUPLEX_MASK 0x100U /*!< The PHY has the 100M full duplex ability.*/
|
||||
#define PHY_100BASETX_HALFDUPLEX_MASK 0x080U /*!< The PHY has the 100M full duplex ability.*/
|
||||
#define PHY_10BASETX_FULLDUPLEX_MASK 0x040U /*!< The PHY has the 10M full duplex ability.*/
|
||||
#define PHY_10BASETX_HALFDUPLEX_MASK 0x020U /*!< The PHY has the 10M full duplex ability.*/
|
||||
|
||||
/*! @brief Defines the PHY status. */
|
||||
enum _phy_status
|
||||
{
|
||||
kStatus_PHY_SMIVisitTimeout = MAKE_STATUS(kStatusGroup_PHY, 1), /*!< ENET PHY SMI visit timeout. */
|
||||
kStatus_PHY_AutoNegotiateFail = MAKE_STATUS(kStatusGroup_PHY, 2) /*!< ENET PHY AutoNegotiate Fail. */
|
||||
};
|
||||
|
||||
/*! @brief Defines the PHY link speed. This is align with the speed for ENET MAC. */
|
||||
typedef enum _phy_speed
|
||||
{
|
||||
kPHY_Speed10M = 0U, /*!< ENET PHY 10M speed. */
|
||||
kPHY_Speed100M /*!< ENET PHY 100M speed. */
|
||||
} phy_speed_t;
|
||||
|
||||
/*! @brief Defines the PHY link duplex. */
|
||||
typedef enum _phy_duplex
|
||||
{
|
||||
kPHY_HalfDuplex = 0U, /*!< ENET PHY half duplex. */
|
||||
kPHY_FullDuplex /*!< ENET PHY full duplex. */
|
||||
} phy_duplex_t;
|
||||
|
||||
/*! @brief Defines the PHY loopback mode. */
|
||||
typedef enum _phy_loop
|
||||
{
|
||||
kPHY_LocalLoop = 0U, /*!< ENET PHY local loopback. */
|
||||
kPHY_RemoteLoop /*!< ENET PHY remote loopback. */
|
||||
} phy_loop_t;
|
||||
|
||||
/*******************************************************************************
|
||||
* API
|
||||
******************************************************************************/
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* @name PHY Driver
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @brief Initializes PHY.
|
||||
*
|
||||
* This function initialize the SMI interface and initialize PHY.
|
||||
* The SMI is the MII management interface between PHY and MAC, which should be
|
||||
* firstly initialized before any other operation for PHY. The PHY initialize with auto-negotiation.
|
||||
*
|
||||
* @param base ENET peripheral base address.
|
||||
* @param phyAddr The PHY address.
|
||||
* @param srcClock_Hz The module clock frequency - system clock for MII management interface - SMI.
|
||||
* @retval kStatus_Success PHY initialize success
|
||||
* @retval kStatus_PHY_SMIVisitTimeout PHY SMI visit time out
|
||||
* @retval kStatus_PHY_AutoNegotiateFail PHY auto negotiate fail
|
||||
*/
|
||||
status_t PHY_Init(ENET_Type *base, uint32_t phyAddr, uint32_t srcClock_Hz);
|
||||
|
||||
/*!
|
||||
* @brief PHY Write function. This function write data over the SMI to
|
||||
* the specified PHY register. This function is called by all PHY interfaces.
|
||||
*
|
||||
* @param base ENET peripheral base address.
|
||||
* @param phyAddr The PHY address.
|
||||
* @param phyReg The PHY register.
|
||||
* @param data The data written to the PHY register.
|
||||
* @retval kStatus_Success PHY write success
|
||||
* @retval kStatus_PHY_SMIVisitTimeout PHY SMI visit time out
|
||||
*/
|
||||
status_t PHY_Write(ENET_Type *base, uint32_t phyAddr, uint32_t phyReg, uint32_t data);
|
||||
|
||||
/*!
|
||||
* @brief PHY Read function. This interface read data over the SMI from the
|
||||
* specified PHY register. This function is called by all PHY interfaces.
|
||||
*
|
||||
* @param base ENET peripheral base address.
|
||||
* @param phyAddr The PHY address.
|
||||
* @param phyReg The PHY register.
|
||||
* @param dataPtr The address to store the data read from the PHY register.
|
||||
* @retval kStatus_Success PHY read success
|
||||
* @retval kStatus_PHY_SMIVisitTimeout PHY SMI visit time out
|
||||
*/
|
||||
status_t PHY_Read(ENET_Type *base, uint32_t phyAddr, uint32_t phyReg, uint32_t *dataPtr);
|
||||
|
||||
/*!
|
||||
* @brief Enables/disables PHY loopback.
|
||||
*
|
||||
* @param base ENET peripheral base address.
|
||||
* @param phyAddr The PHY address.
|
||||
* @param mode The loopback mode to be enabled, please see "phy_loop_t".
|
||||
* the two loopback mode should not be both set. when one loopback mode is set
|
||||
* the other one should be disabled.
|
||||
* @param speed PHY speed for loopback mode.
|
||||
* @param enable True to enable, false to disable.
|
||||
* @retval kStatus_Success PHY loopback success
|
||||
* @retval kStatus_PHY_SMIVisitTimeout PHY SMI visit time out
|
||||
*/
|
||||
status_t PHY_EnableLoopback(ENET_Type *base, uint32_t phyAddr, phy_loop_t mode, phy_speed_t speed, bool enable);
|
||||
|
||||
/*!
|
||||
* @brief Gets the PHY link status.
|
||||
*
|
||||
* @param base ENET peripheral base address.
|
||||
* @param phyAddr The PHY address.
|
||||
* @param status The link up or down status of the PHY.
|
||||
* - true the link is up.
|
||||
* - false the link is down.
|
||||
* @retval kStatus_Success PHY get link status success
|
||||
* @retval kStatus_PHY_SMIVisitTimeout PHY SMI visit time out
|
||||
*/
|
||||
status_t PHY_GetLinkStatus(ENET_Type *base, uint32_t phyAddr, bool *status);
|
||||
|
||||
/*!
|
||||
* @brief Gets the PHY link speed and duplex.
|
||||
*
|
||||
* @param base ENET peripheral base address.
|
||||
* @param phyAddr The PHY address.
|
||||
* @param speed The address of PHY link speed.
|
||||
* @param duplex The link duplex of PHY.
|
||||
* @retval kStatus_Success PHY get link speed and duplex success
|
||||
* @retval kStatus_PHY_SMIVisitTimeout PHY SMI visit time out
|
||||
*/
|
||||
status_t PHY_GetLinkSpeedDuplex(ENET_Type *base, uint32_t phyAddr, phy_speed_t *speed, phy_duplex_t *duplex);
|
||||
|
||||
/* @} */
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
/*! @}*/
|
||||
|
||||
#endif /* _FSL_PHY_H_ */
|
||||
@@ -157,6 +157,7 @@ void SystemCoreClockUpdate (void) {
|
||||
case CCM_CBCMR_PERIPH_CLK2_SEL(2U):
|
||||
freq = (((CCM_ANALOG->PLL_SYS & CCM_ANALOG_PLL_SYS_BYPASS_CLK_SRC_MASK) >> CCM_ANALOG_PLL_SYS_BYPASS_CLK_SRC_SHIFT) == 0U) ?
|
||||
CPU_XTAL_CLK_HZ : CPU_CLK1_HZ;
|
||||
break;
|
||||
|
||||
case CCM_CBCMR_PERIPH_CLK2_SEL(3U):
|
||||
default:
|
||||
|
||||
@@ -4,4 +4,8 @@ ifeq ($(CONFIG_BSP_USING_LPUART),y)
|
||||
SRC_DIR += uart
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_BSP_USING_LWIP),y)
|
||||
SRC_DIR += ethernet
|
||||
endif
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
SRC_FILES := enet_ethernetif.c enet_ethernetif_kinetis.c
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
||||
+324
@@ -0,0 +1,324 @@
|
||||
/*
|
||||
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the lwIP TCP/IP stack.
|
||||
*
|
||||
* Author: Adam Dunkels <adam@sics.se>
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2013-2016, Freescale Semiconductor, Inc.
|
||||
* Copyright 2016-2019 NXP
|
||||
* All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2021 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file enet_ethernetif.c
|
||||
* @brief ethernet drivers
|
||||
* @version 1.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2021.11.11
|
||||
*/
|
||||
|
||||
#include "lwip/opt.h"
|
||||
#include "lwip/def.h"
|
||||
#include "lwip/mem.h"
|
||||
#include "lwip/pbuf.h"
|
||||
#include "lwip/stats.h"
|
||||
#include "lwip/snmp.h"
|
||||
#include "lwip/ethip6.h"
|
||||
#include "netif/etharp.h"
|
||||
#include "netif/ppp/pppoe.h"
|
||||
#include "lwip/igmp.h"
|
||||
#include "lwip/mld6.h"
|
||||
|
||||
#if USE_RTOS && defined(FSL_RTOS_FREE_RTOS)
|
||||
//#include "FreeRTOS.h"
|
||||
//#include "event_groups.h"
|
||||
#endif
|
||||
|
||||
#include "netif/ethernet.h"
|
||||
#include "enet_ethernetif.h"
|
||||
#include "enet_ethernetif_priv.h"
|
||||
|
||||
#include "fsl_enet.h"
|
||||
#include "fsl_phy.h"
|
||||
#include "fsl_gpio.h"
|
||||
#include "fsl_iomuxc.h"
|
||||
|
||||
#include "sys_arch.h"
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* Code
|
||||
******************************************************************************/
|
||||
|
||||
void enet_delay(void)
|
||||
{
|
||||
volatile uint32_t i = 0;
|
||||
for (i = 0; i < 1000000; ++i)
|
||||
{
|
||||
__asm("NOP"); /* delay */
|
||||
}
|
||||
}
|
||||
|
||||
void Time_Update_LwIP(void)
|
||||
{
|
||||
}
|
||||
|
||||
void ethernetif_clk_init(void)
|
||||
{
|
||||
const clock_enet_pll_config_t config = {.enableClkOutput = true, .enableClkOutput25M = false, .loopDivider = 1};
|
||||
CLOCK_InitEnetPll(&config);
|
||||
SysTick_Config(USEC_TO_COUNT(1000U, CLOCK_GetFreq(kCLOCK_CoreSysClk)));
|
||||
}
|
||||
|
||||
void ethernetif_gpio_init(void)
|
||||
{
|
||||
gpio_pin_config_t gpio_config = {kGPIO_DigitalOutput, 0, kGPIO_NoIntmode};
|
||||
|
||||
IOMUXC_EnableMode(IOMUXC_GPR, kIOMUXC_GPR_ENET1TxClkOutputDir, true);
|
||||
|
||||
GPIO_PinInit(GPIO1, 3, &gpio_config);
|
||||
GPIO_PinInit(GPIO1, 10, &gpio_config);
|
||||
/* pull up the ENET_INT before RESET. */
|
||||
GPIO_WritePinOutput(GPIO1, 10, 1);
|
||||
GPIO_WritePinOutput(GPIO1, 3, 0);
|
||||
enet_delay();
|
||||
GPIO_WritePinOutput(GPIO1, 3, 1);
|
||||
}
|
||||
|
||||
void ETH_BSP_Config(void)
|
||||
{
|
||||
static int flag = 0;
|
||||
if(flag == 0)
|
||||
{
|
||||
ethernetif_clk_init();
|
||||
ethernetif_gpio_init();
|
||||
flag = 1;
|
||||
}
|
||||
}
|
||||
|
||||
void ethernetif_phy_init(struct ethernetif *ethernetif,
|
||||
const ethernetif_config_t *ethernetifConfig,
|
||||
enet_config_t *config)
|
||||
{
|
||||
uint32_t sysClock;
|
||||
status_t status;
|
||||
bool link = false;
|
||||
uint32_t count = 0;
|
||||
phy_speed_t speed;
|
||||
phy_duplex_t duplex;
|
||||
|
||||
sysClock = CLOCK_GetFreq(ethernetifConfig->clockName);
|
||||
|
||||
LWIP_PLATFORM_DIAG(("Initializing PHY...\r\n"));
|
||||
|
||||
while ((count < ENET_ATONEGOTIATION_TIMEOUT) && (!link))
|
||||
{
|
||||
status = PHY_Init(*ethernetif_enet_ptr(ethernetif), ethernetifConfig->phyAddress, sysClock);
|
||||
|
||||
if (kStatus_Success == status)
|
||||
{
|
||||
PHY_GetLinkStatus(*ethernetif_enet_ptr(ethernetif), ethernetifConfig->phyAddress, &link);
|
||||
}
|
||||
else if (kStatus_PHY_AutoNegotiateFail == status)
|
||||
{
|
||||
LWIP_PLATFORM_DIAG(("PHY Auto-negotiation failed. Please check the ENET cable connection and link partner setting."));
|
||||
}
|
||||
else
|
||||
{
|
||||
LWIP_ASSERT("\r\nCannot initialize PHY.\r\n", 0);
|
||||
}
|
||||
|
||||
count++;
|
||||
}
|
||||
|
||||
if (link)
|
||||
{
|
||||
/* Get the actual PHY link speed. */
|
||||
PHY_GetLinkSpeedDuplex(*ethernetif_enet_ptr(ethernetif), ethernetifConfig->phyAddress, &speed, &duplex);
|
||||
/* Change the MII speed and duplex for actual link status. */
|
||||
config->miiSpeed = (enet_mii_speed_t)speed;
|
||||
config->miiDuplex = (enet_mii_duplex_t)duplex;
|
||||
}
|
||||
#if 0 /* Disable assert. If initial auto-negation is timeout, \ \
|
||||
the ENET is set to default (100Mbs and full-duplex). */
|
||||
else
|
||||
{
|
||||
LWIP_ASSERT("\r\nGiving up PHY initialization. Please check the ENET cable connection and link partner setting and reset the board.\r\n", 0);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* This function should be called when a packet is ready to be read
|
||||
* from the interface. It uses the function ethernetif_linkinput() that
|
||||
* should handle the actual reception of bytes from the network
|
||||
* interface. Then the type of the received packet is determined and
|
||||
* the appropriate input function is called.
|
||||
*
|
||||
* @param netif the lwip network interface structure for this ethernetif
|
||||
*/
|
||||
|
||||
void ethernetif_input(struct netif *netif)
|
||||
{
|
||||
struct pbuf *p;
|
||||
|
||||
LWIP_ASSERT("netif != NULL", (netif != NULL));
|
||||
|
||||
/* move received packet into a new pbuf */
|
||||
while ((p = ethernetif_linkinput(netif)) != NULL)
|
||||
{
|
||||
/* pass all packets to ethernet_input, which decides what packets it supports */
|
||||
if (netif->input(p, netif) != ERR_OK)
|
||||
{
|
||||
LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_input: IP input error\n"));
|
||||
pbuf_free(p);
|
||||
p = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static ENET_Type *ethernetif_get_enet_base(const uint8_t enetIdx)
|
||||
{
|
||||
ENET_Type* enets[] = ENET_BASE_PTRS;
|
||||
int arrayIdx;
|
||||
int enetCount;
|
||||
|
||||
for (arrayIdx = 0, enetCount = 0; arrayIdx < ARRAY_SIZE(enets); arrayIdx++)
|
||||
{
|
||||
if (enets[arrayIdx] != 0U) /* process only defined positions */
|
||||
{ /* (some SOC headers count ENETs from 1 instead of 0) */
|
||||
if (enetCount == enetIdx)
|
||||
{
|
||||
return enets[arrayIdx];
|
||||
}
|
||||
enetCount++;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
err_t ethernetif_init(struct netif *netif, struct ethernetif *ethernetif,
|
||||
const uint8_t enetIdx,
|
||||
const ethernetif_config_t *ethernetifConfig)
|
||||
{
|
||||
LWIP_ASSERT("netif != NULL", (netif != NULL));
|
||||
LWIP_ASSERT("ethernetifConfig != NULL", (ethernetifConfig != NULL));
|
||||
|
||||
#if LWIP_NETIF_HOSTNAME
|
||||
/* Initialize interface hostname */
|
||||
netif->hostname = "lwip";
|
||||
#endif /* LWIP_NETIF_HOSTNAME */
|
||||
|
||||
/*
|
||||
* Initialize the snmp variables and counters inside the struct netif.
|
||||
* The last argument should be replaced with your link speed, in units
|
||||
* of bits per second.
|
||||
*/
|
||||
MIB2_INIT_NETIF(netif, snmp_ifType_ethernet_csmacd, LINK_SPEED_OF_YOUR_NETIF_IN_BPS);
|
||||
|
||||
netif->state = ethernetif;
|
||||
netif->name[0] = IFNAME0;
|
||||
netif->name[1] = IFNAME1;
|
||||
/* We directly use etharp_output() here to save a function call.
|
||||
* You can instead declare your own function an call etharp_output()
|
||||
* from it if you have to do some checks before sending (e.g. if link
|
||||
* is available...) */
|
||||
#if LWIP_IPV4
|
||||
netif->output = etharp_output;
|
||||
#endif
|
||||
#if LWIP_IPV6
|
||||
netif->output_ip6 = ethip6_output;
|
||||
#endif /* LWIP_IPV6 */
|
||||
netif->linkoutput = ethernetif_linkoutput;
|
||||
|
||||
#if LWIP_IPV4 && LWIP_IGMP
|
||||
netif_set_igmp_mac_filter(netif, ethernetif_igmp_mac_filter);
|
||||
netif->flags |= NETIF_FLAG_IGMP;
|
||||
#endif
|
||||
#if LWIP_IPV6 && LWIP_IPV6_MLD
|
||||
netif_set_mld_mac_filter(netif, ethernetif_mld_mac_filter);
|
||||
netif->flags |= NETIF_FLAG_MLD6;
|
||||
#endif
|
||||
|
||||
/* Init ethernetif parameters.*/
|
||||
*ethernetif_enet_ptr(ethernetif) = ethernetif_get_enet_base(enetIdx);
|
||||
LWIP_ASSERT("*ethernetif_enet_ptr(ethernetif) != NULL", (*ethernetif_enet_ptr(ethernetif) != NULL));
|
||||
|
||||
/* set MAC hardware address length */
|
||||
netif->hwaddr_len = ETH_HWADDR_LEN;
|
||||
|
||||
/* set MAC hardware address */
|
||||
memcpy(netif->hwaddr, ethernetifConfig->macAddress, NETIF_MAX_HWADDR_LEN);
|
||||
|
||||
/* maximum transfer unit */
|
||||
netif->mtu = 1500; /* TODO: define a config */
|
||||
|
||||
/* device capabilities */
|
||||
/* don't set NETIF_FLAG_ETHARP if this device is not an ethernet one */
|
||||
netif->flags |= NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP;
|
||||
|
||||
/* ENET driver initialization.*/
|
||||
ethernetif_enet_init(netif, ethernetif, ethernetifConfig);
|
||||
|
||||
#if LWIP_IPV6 && LWIP_IPV6_MLD
|
||||
/*
|
||||
* For hardware/netifs that implement MAC filtering.
|
||||
* All-nodes link-local is handled by default, so we must let the hardware know
|
||||
* to allow multicast packets in.
|
||||
* Should set mld_mac_filter previously. */
|
||||
if (netif->mld_mac_filter != NULL)
|
||||
{
|
||||
ip6_addr_t ip6_allnodes_ll;
|
||||
ip6_addr_set_allnodes_linklocal(&ip6_allnodes_ll);
|
||||
netif->mld_mac_filter(netif, &ip6_allnodes_ll, NETIF_ADD_MAC_FILTER);
|
||||
}
|
||||
#endif /* LWIP_IPV6 && LWIP_IPV6_MLD */
|
||||
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
+202
@@ -0,0 +1,202 @@
|
||||
/*
|
||||
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the lwIP TCP/IP stack.
|
||||
*
|
||||
* Author: Adam Dunkels <adam@sics.se>
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2013-2016, Freescale Semiconductor, Inc.
|
||||
* Copyright 2016-2019 NXP
|
||||
* All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2021 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file enet_ethernetif.h
|
||||
* @brief ethernet drivers
|
||||
* @version 1.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2021.11.11
|
||||
*/
|
||||
|
||||
|
||||
#ifndef ENET_ETHERNETIF_H
|
||||
#define ENET_ETHERNETIF_H
|
||||
|
||||
#include "lwip/err.h"
|
||||
#include "lwip/netif.h"
|
||||
#include "fsl_enet.h"
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
#ifndef ENET_RXBD_NUM
|
||||
#define ENET_RXBD_NUM (5)
|
||||
#endif
|
||||
#ifndef ENET_TXBD_NUM
|
||||
#if defined(FSL_FEATURE_SOC_LPC_ENET_COUNT) && (FSL_FEATURE_SOC_LPC_ENET_COUNT > 0)
|
||||
#define ENET_TXBD_NUM (5)
|
||||
#else
|
||||
#define ENET_TXBD_NUM (3)
|
||||
#endif
|
||||
#endif
|
||||
#ifndef ENET_RXBUFF_SIZE
|
||||
#if defined(FSL_FEATURE_SOC_LPC_ENET_COUNT) && (FSL_FEATURE_SOC_LPC_ENET_COUNT > 0)
|
||||
#define ENET_RXBUFF_SIZE (ENET_FRAME_MAX_FRAMELEN + ETH_PAD_SIZE)
|
||||
#else
|
||||
#define ENET_RXBUFF_SIZE ENET_FRAME_MAX_FRAMELEN
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef ENET_TXBUFF_SIZE
|
||||
#define ENET_TXBUFF_SIZE (ENET_FRAME_MAX_FRAMELEN)
|
||||
#endif
|
||||
|
||||
#define ENET_TIMEOUT (0xFFFU)
|
||||
|
||||
/* ENET IRQ priority. Used in FreeRTOS. */
|
||||
/* Interrupt priorities. */
|
||||
#ifdef __CA7_REV
|
||||
#ifndef ENET_PRIORITY
|
||||
#define ENET_PRIORITY (21U)
|
||||
#endif
|
||||
#ifndef ENET_1588_PRIORITY
|
||||
#define ENET_1588_PRIORITY (20U)
|
||||
#endif
|
||||
#else
|
||||
#ifndef ENET_PRIORITY
|
||||
#define ENET_PRIORITY (6U)
|
||||
#endif
|
||||
#ifndef ENET_1588_PRIORITY
|
||||
#define ENET_1588_PRIORITY (5U)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Defines Ethernet Autonegotiation Timeout during initialization.
|
||||
* Set it to 0 to disable the waiting. */
|
||||
#ifndef ENET_ATONEGOTIATION_TIMEOUT
|
||||
#define ENET_ATONEGOTIATION_TIMEOUT (0xFFFU)
|
||||
#endif
|
||||
|
||||
/* Define those to better describe your network interface. */
|
||||
#define IFNAME0 'e'
|
||||
#define IFNAME1 'n'
|
||||
|
||||
#if defined(FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL) && FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL
|
||||
#if defined(FSL_FEATURE_L2CACHE_LINESIZE_BYTE) \
|
||||
&& ((!defined(FSL_SDK_DISBLE_L2CACHE_PRESENT)) || (FSL_SDK_DISBLE_L2CACHE_PRESENT == 0))
|
||||
#if defined(FSL_FEATURE_L1DCACHE_LINESIZE_BYTE)
|
||||
#define FSL_CACHE_LINESIZE_MAX MAX(FSL_FEATURE_L1DCACHE_LINESIZE_BYTE, FSL_FEATURE_L2CACHE_LINESIZE_BYTE)
|
||||
#define FSL_ENET_BUFF_ALIGNMENT MAX(ENET_BUFF_ALIGNMENT, FSL_CACHE_LINESIZE_MAX)
|
||||
#else
|
||||
#define FSL_ENET_BUFF_ALIGNMENT MAX(ENET_BUFF_ALIGNMENT, FSL_FEATURE_L2CACHE_LINESIZE_BYTE)
|
||||
#endif
|
||||
#elif defined(FSL_FEATURE_L1DCACHE_LINESIZE_BYTE)
|
||||
#define FSL_ENET_BUFF_ALIGNMENT MAX(ENET_BUFF_ALIGNMENT, FSL_FEATURE_L1DCACHE_LINESIZE_BYTE)
|
||||
#else
|
||||
#define FSL_ENET_BUFF_ALIGNMENT ENET_BUFF_ALIGNMENT
|
||||
#endif
|
||||
#else
|
||||
#define FSL_ENET_BUFF_ALIGNMENT ENET_BUFF_ALIGNMENT
|
||||
#endif
|
||||
|
||||
#define ENET_RING_NUM 1U
|
||||
|
||||
typedef uint8_t rx_buffer_t[SDK_SIZEALIGN(ENET_RXBUFF_SIZE, FSL_ENET_BUFF_ALIGNMENT)];
|
||||
typedef uint8_t tx_buffer_t[SDK_SIZEALIGN(ENET_TXBUFF_SIZE, FSL_ENET_BUFF_ALIGNMENT)];
|
||||
|
||||
#if (defined(FSL_FEATURE_SOC_LPC_ENET_COUNT) && (FSL_FEATURE_SOC_LPC_ENET_COUNT > 0))
|
||||
typedef struct mem_range
|
||||
{
|
||||
uint32_t start;
|
||||
uint32_t end;
|
||||
} mem_range_t;
|
||||
#endif /* FSL_FEATURE_SOC_LPC_ENET_COUNT */
|
||||
|
||||
/**
|
||||
* Helper struct to hold data for configuration of ethernet interface.
|
||||
*/
|
||||
typedef struct ethernetif_config
|
||||
{
|
||||
uint32_t phyAddress;
|
||||
clock_name_t clockName;
|
||||
uint8_t macAddress[NETIF_MAX_HWADDR_LEN];
|
||||
#if (defined(FSL_FEATURE_SOC_LPC_ENET_COUNT) && (FSL_FEATURE_SOC_LPC_ENET_COUNT > 0))
|
||||
const mem_range_t *non_dma_memory;
|
||||
#endif /* FSL_FEATURE_SOC_LPC_ENET_COUNT */
|
||||
} ethernetif_config_t;
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/**
|
||||
* This function should be passed as a parameter to netif_add()
|
||||
* if you initialize the first ENET interface.
|
||||
*/
|
||||
err_t ethernetif0_init(struct netif *netif);
|
||||
|
||||
#if (defined(FSL_FEATURE_SOC_ENET_COUNT) && (FSL_FEATURE_SOC_ENET_COUNT > 1)) \
|
||||
|| (defined(FSL_FEATURE_SOC_LPC_ENET_COUNT) && (FSL_FEATURE_SOC_LPC_ENET_COUNT > 1))
|
||||
/**
|
||||
* This function should be passed as a parameter to netif_add()
|
||||
* if you initialize the second ENET interface.
|
||||
*/
|
||||
err_t ethernetif1_init(struct netif *netif);
|
||||
#endif /* FSL_FEATURE_SOC_*_ENET_COUNT */
|
||||
|
||||
/**
|
||||
* This function should be called when a packet is ready to be read
|
||||
* from the interface.
|
||||
* It is used by bare-metal applications.
|
||||
*
|
||||
* @param netif the lwip network interface structure for this ethernetif
|
||||
*/
|
||||
void ethernetif_input( struct netif *netif);
|
||||
|
||||
void ETH_BSP_Config(void);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* ENET_ETHERNETIF_H */
|
||||
+646
@@ -0,0 +1,646 @@
|
||||
/*
|
||||
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the lwIP TCP/IP stack.
|
||||
*
|
||||
* Author: Adam Dunkels <adam@sics.se>
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2013-2016, Freescale Semiconductor, Inc.
|
||||
* Copyright 2016-2019 NXP
|
||||
* All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2021 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file enet_ethernetif_kinetis.c
|
||||
* @brief ethernet drivers
|
||||
* @version 1.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2021.11.11
|
||||
*/
|
||||
|
||||
#include "lwip/opt.h"
|
||||
#include "lwip/def.h"
|
||||
#include "lwip/mem.h"
|
||||
#include "lwip/pbuf.h"
|
||||
#include "lwip/stats.h"
|
||||
#include "lwip/snmp.h"
|
||||
#include "lwip/ethip6.h"
|
||||
#include "netif/etharp.h"
|
||||
#include "netif/ppp/pppoe.h"
|
||||
#include "lwip/igmp.h"
|
||||
#include "lwip/mld6.h"
|
||||
|
||||
#if USE_RTOS && defined(FSL_RTOS_FREE_RTOS)
|
||||
#include "FreeRTOS.h"
|
||||
#include "event_groups.h"
|
||||
|
||||
#include "list.h"
|
||||
|
||||
typedef uint32_t TickType_t;
|
||||
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
||||
|
||||
typedef TickType_t EventBits_t;
|
||||
|
||||
typedef long BaseType_t;
|
||||
typedef unsigned long UBaseType_t;
|
||||
|
||||
#define portBASE_TYPE long
|
||||
|
||||
#define pdFALSE ( ( BaseType_t ) 0 )
|
||||
#define pdTRUE ( ( BaseType_t ) 1 )
|
||||
|
||||
#define pdPASS ( pdTRUE )
|
||||
#define pdFAIL ( pdFALSE )
|
||||
|
||||
|
||||
typedef struct EventGroupDef_t
|
||||
{
|
||||
EventBits_t uxEventBits;
|
||||
List_t xTasksWaitingForBits; /*< List of tasks waiting for a bit to be set. */
|
||||
|
||||
#if ( configUSE_TRACE_FACILITY == 1 )
|
||||
UBaseType_t uxEventGroupNumber;
|
||||
#endif
|
||||
|
||||
#if ( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) )
|
||||
uint8_t ucStaticallyAllocated; /*< Set to pdTRUE if the event group is statically allocated to ensure no attempt is made to free the memory. */
|
||||
#endif
|
||||
} EventGroup_t;
|
||||
|
||||
struct EventGroupDef_t;
|
||||
typedef struct EventGroupDef_t * EventGroupHandle_t;
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
#include "enet_ethernetif.h"
|
||||
#include "enet_ethernetif_priv.h"
|
||||
|
||||
#include "fsl_enet.h"
|
||||
#include "fsl_phy.h"
|
||||
|
||||
#include "sys_arch.h"
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
|
||||
/**
|
||||
* Helper struct to hold private data used to operate your ethernet interface.
|
||||
*/
|
||||
struct ethernetif
|
||||
{
|
||||
ENET_Type *base;
|
||||
#if (defined(FSL_FEATURE_SOC_ENET_COUNT) && (FSL_FEATURE_SOC_ENET_COUNT > 0)) || \
|
||||
(USE_RTOS && defined(FSL_RTOS_FREE_RTOS))
|
||||
enet_handle_t handle;
|
||||
#endif
|
||||
#if USE_RTOS && defined(FSL_RTOS_FREE_RTOS)
|
||||
EventGroupHandle_t enetTransmitAccessEvent;
|
||||
EventBits_t txFlag;
|
||||
#endif
|
||||
enet_rx_bd_struct_t *RxBuffDescrip;
|
||||
enet_tx_bd_struct_t *TxBuffDescrip;
|
||||
rx_buffer_t *RxDataBuff;
|
||||
tx_buffer_t *TxDataBuff;
|
||||
};
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* Code
|
||||
******************************************************************************/
|
||||
#if USE_RTOS && defined(FSL_RTOS_FREE_RTOS)
|
||||
#if FSL_FEATURE_ENET_QUEUE > 1
|
||||
static void ethernet_callback(ENET_Type *base, enet_handle_t *handle, uint32_t ringId, enet_event_t event, void *param)
|
||||
#else
|
||||
static void ethernet_callback(ENET_Type *base, enet_handle_t *handle, enet_event_t event, void *param)
|
||||
#endif /* FSL_FEATURE_ENET_QUEUE */
|
||||
{
|
||||
struct netif *netif = (struct netif *)param;
|
||||
struct ethernetif *ethernetif = netif->state;
|
||||
BaseType_t xResult;
|
||||
|
||||
|
||||
switch (event)
|
||||
{
|
||||
case kENET_RxEvent:
|
||||
ethernetif_input(netif);
|
||||
break;
|
||||
case kENET_TxEvent:
|
||||
{
|
||||
portBASE_TYPE taskToWake = pdFALSE;
|
||||
|
||||
#ifdef __CA7_REV
|
||||
if (SystemGetIRQNestingLevel())
|
||||
#else
|
||||
if (__get_IPSR())
|
||||
#endif
|
||||
{
|
||||
xResult = xEventGroupSetBitsFromISR(ethernetif->enetTransmitAccessEvent, ethernetif->txFlag, &taskToWake);
|
||||
if ((pdPASS == xResult) && (pdTRUE == taskToWake))
|
||||
{
|
||||
portYIELD_FROM_ISR(taskToWake);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
xEventGroupSetBits(ethernetif->enetTransmitAccessEvent, ethernetif->txFlag);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if LWIP_IPV4 && LWIP_IGMP
|
||||
err_t ethernetif_igmp_mac_filter(struct netif *netif, const ip4_addr_t *group,
|
||||
enum netif_mac_filter_action action)
|
||||
{
|
||||
struct ethernetif *ethernetif = netif->state;
|
||||
uint8_t multicastMacAddr[6];
|
||||
err_t result;
|
||||
|
||||
multicastMacAddr[0] = 0x01U;
|
||||
multicastMacAddr[1] = 0x00U;
|
||||
multicastMacAddr[2] = 0x5EU;
|
||||
multicastMacAddr[3] = (group->addr >> 8) & 0x7FU;
|
||||
multicastMacAddr[4] = (group->addr >> 16) & 0xFFU;
|
||||
multicastMacAddr[5] = (group->addr >> 24) & 0xFFU;
|
||||
|
||||
switch (action)
|
||||
{
|
||||
case IGMP_ADD_MAC_FILTER:
|
||||
/* Adds the ENET device to a multicast group.*/
|
||||
ENET_AddMulticastGroup(ethernetif->base, multicastMacAddr);
|
||||
result = ERR_OK;
|
||||
break;
|
||||
case IGMP_DEL_MAC_FILTER:
|
||||
/*
|
||||
* Moves the ENET device from a multicast group.
|
||||
* Since the ENET_LeaveMulticastGroup() could filter out also other
|
||||
* group addresses having the same hash, the call is commented out.
|
||||
*/
|
||||
/* ENET_LeaveMulticastGroup(ethernetif->base, multicastMacAddr); */
|
||||
result = ERR_OK;
|
||||
break;
|
||||
default:
|
||||
result = ERR_IF;
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if LWIP_IPV6 && LWIP_IPV6_MLD
|
||||
err_t ethernetif_mld_mac_filter(struct netif *netif, const ip6_addr_t *group,
|
||||
enum netif_mac_filter_action action)
|
||||
{
|
||||
struct ethernetif *ethernetif = netif->state;
|
||||
uint8_t multicastMacAddr[6];
|
||||
err_t result;
|
||||
|
||||
multicastMacAddr[0] = 0x33U;
|
||||
multicastMacAddr[1] = 0x33U;
|
||||
multicastMacAddr[2] = (group->addr[3]) & 0xFFU;
|
||||
multicastMacAddr[3] = (group->addr[3] >> 8) & 0xFFU;
|
||||
multicastMacAddr[4] = (group->addr[3] >> 16) & 0xFFU;
|
||||
multicastMacAddr[5] = (group->addr[3] >> 24) & 0xFFU;
|
||||
|
||||
switch (action)
|
||||
{
|
||||
case NETIF_ADD_MAC_FILTER:
|
||||
/* Adds the ENET device to a multicast group.*/
|
||||
ENET_AddMulticastGroup(ethernetif->base, multicastMacAddr);
|
||||
result = ERR_OK;
|
||||
break;
|
||||
case NETIF_DEL_MAC_FILTER:
|
||||
/*
|
||||
* Moves the ENET device from a multicast group.
|
||||
* Since the ENET_LeaveMulticastGroup() could filter out also other
|
||||
* group addresses having the same hash, the call is commented out.
|
||||
*/
|
||||
/* ENET_LeaveMulticastGroup(ethernetif->base, multicastMacAddr); */
|
||||
result = ERR_OK;
|
||||
break;
|
||||
default:
|
||||
result = ERR_IF;
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Initializes ENET driver.
|
||||
*/
|
||||
void ethernetif_enet_init(struct netif *netif, struct ethernetif *ethernetif,
|
||||
const ethernetif_config_t *ethernetifConfig)
|
||||
{
|
||||
enet_config_t config;
|
||||
uint32_t sysClock;
|
||||
enet_buffer_config_t buffCfg[ENET_RING_NUM];
|
||||
|
||||
/* prepare the buffer configuration. */
|
||||
buffCfg[0].rxBdNumber = ENET_RXBD_NUM; /* Receive buffer descriptor number. */
|
||||
buffCfg[0].txBdNumber = ENET_TXBD_NUM; /* Transmit buffer descriptor number. */
|
||||
buffCfg[0].rxBuffSizeAlign = sizeof(rx_buffer_t); /* Aligned receive data buffer size. */
|
||||
buffCfg[0].txBuffSizeAlign = sizeof(tx_buffer_t); /* Aligned transmit data buffer size. */
|
||||
buffCfg[0].rxBdStartAddrAlign = &(ethernetif->RxBuffDescrip[0]); /* Aligned receive buffer descriptor start address. */
|
||||
buffCfg[0].txBdStartAddrAlign = &(ethernetif->TxBuffDescrip[0]); /* Aligned transmit buffer descriptor start address. */
|
||||
buffCfg[0].rxBufferAlign = &(ethernetif->RxDataBuff[0][0]); /* Receive data buffer start address. */
|
||||
buffCfg[0].txBufferAlign = &(ethernetif->TxDataBuff[0][0]); /* Transmit data buffer start address. */
|
||||
|
||||
sysClock = CLOCK_GetFreq(ethernetifConfig->clockName);
|
||||
|
||||
ENET_GetDefaultConfig(&config);
|
||||
config.ringNum = ENET_RING_NUM;
|
||||
|
||||
ethernetif_phy_init(ethernetif, ethernetifConfig, &config);
|
||||
|
||||
#if USE_RTOS && defined(FSL_RTOS_FREE_RTOS)
|
||||
uint32_t instance;
|
||||
static ENET_Type *const enetBases[] = ENET_BASE_PTRS;
|
||||
static const IRQn_Type enetTxIrqId[] = ENET_Transmit_IRQS;
|
||||
/*! @brief Pointers to enet receive IRQ number for each instance. */
|
||||
static const IRQn_Type enetRxIrqId[] = ENET_Receive_IRQS;
|
||||
#if defined(ENET_ENHANCEDBUFFERDESCRIPTOR_MODE) && ENET_ENHANCEDBUFFERDESCRIPTOR_MODE
|
||||
/*! @brief Pointers to enet timestamp IRQ number for each instance. */
|
||||
static const IRQn_Type enetTsIrqId[] = ENET_1588_Timer_IRQS;
|
||||
#endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */
|
||||
|
||||
/* Create the Event for transmit busy release trigger. */
|
||||
ethernetif->enetTransmitAccessEvent = xEventGroupCreate();
|
||||
ethernetif->txFlag = 0x1;
|
||||
|
||||
config.interrupt |= kENET_RxFrameInterrupt | kENET_TxFrameInterrupt | kENET_TxBufferInterrupt;
|
||||
|
||||
for (instance = 0; instance < ARRAY_SIZE(enetBases); instance++)
|
||||
{
|
||||
if (enetBases[instance] == ethernetif->base)
|
||||
{
|
||||
#ifdef __CA7_REV
|
||||
GIC_SetPriority(enetRxIrqId[instance], ENET_PRIORITY);
|
||||
GIC_SetPriority(enetTxIrqId[instance], ENET_PRIORITY);
|
||||
#if defined(ENET_ENHANCEDBUFFERDESCRIPTOR_MODE) && ENET_ENHANCEDBUFFERDESCRIPTOR_MODE
|
||||
GIC_SetPriority(enetTsIrqId[instance], ENET_1588_PRIORITY);
|
||||
#endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */
|
||||
#else
|
||||
NVIC_SetPriority(enetRxIrqId[instance], ENET_PRIORITY);
|
||||
NVIC_SetPriority(enetTxIrqId[instance], ENET_PRIORITY);
|
||||
#if defined(ENET_ENHANCEDBUFFERDESCRIPTOR_MODE) && ENET_ENHANCEDBUFFERDESCRIPTOR_MODE
|
||||
NVIC_SetPriority(enetTsIrqId[instance], ENET_1588_PRIORITY);
|
||||
#endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */
|
||||
#endif /* __CA7_REV */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
LWIP_ASSERT("Input Ethernet base error!", (instance != ARRAY_SIZE(enetBases)));
|
||||
#endif /* USE_RTOS */
|
||||
|
||||
/* Initialize the ENET module.*/
|
||||
ENET_Init(ethernetif->base, ðernetif->handle, &config, &buffCfg[0], netif->hwaddr, sysClock);
|
||||
|
||||
#if USE_RTOS && defined(FSL_RTOS_FREE_RTOS)
|
||||
ENET_SetCallback(ðernetif->handle, ethernet_callback, netif);
|
||||
#endif
|
||||
|
||||
ENET_ActiveRead(ethernetif->base);
|
||||
}
|
||||
|
||||
ENET_Type **ethernetif_enet_ptr(struct ethernetif *ethernetif)
|
||||
{
|
||||
return &(ethernetif->base);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns next buffer for TX.
|
||||
* Can wait if no buffer available.
|
||||
*/
|
||||
static unsigned char *enet_get_tx_buffer(struct ethernetif *ethernetif)
|
||||
{
|
||||
static unsigned char ucBuffer[ENET_FRAME_MAX_FRAMELEN];
|
||||
return ucBuffer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends frame via ENET.
|
||||
*/
|
||||
static err_t enet_send_frame(struct ethernetif *ethernetif, unsigned char *data, const uint32_t length)
|
||||
{
|
||||
#if USE_RTOS && defined(FSL_RTOS_FREE_RTOS)
|
||||
{
|
||||
status_t result;
|
||||
|
||||
do
|
||||
{
|
||||
result = ENET_SendFrame(ethernetif->base, ðernetif->handle, data, length);
|
||||
|
||||
if (result == kStatus_ENET_TxFrameBusy)
|
||||
{
|
||||
xEventGroupWaitBits(ethernetif->enetTransmitAccessEvent, ethernetif->txFlag, pdTRUE, (BaseType_t) false,
|
||||
portMAX_DELAY);
|
||||
}
|
||||
|
||||
} while (result == kStatus_ENET_TxFrameBusy);
|
||||
return ERR_OK;
|
||||
}
|
||||
#else
|
||||
{
|
||||
uint32_t counter;
|
||||
|
||||
for (counter = ENET_TIMEOUT; counter != 0U; counter--)
|
||||
{
|
||||
if (ENET_SendFrame(ethernetif->base, ðernetif->handle, data, length) != kStatus_ENET_TxFrameBusy)
|
||||
{
|
||||
return ERR_OK;
|
||||
}
|
||||
}
|
||||
|
||||
return ERR_TIMEOUT;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
struct pbuf *ethernetif_linkinput(struct netif *netif)
|
||||
{
|
||||
struct ethernetif *ethernetif = netif->state;
|
||||
struct pbuf *p = NULL;
|
||||
struct pbuf *q;
|
||||
uint32_t len;
|
||||
status_t status;
|
||||
|
||||
/* Obtain the size of the packet and put it into the "len"
|
||||
variable. */
|
||||
status = ENET_GetRxFrameSize(ðernetif->handle, &len);
|
||||
|
||||
if (kStatus_ENET_RxFrameEmpty != status)
|
||||
{
|
||||
/* Call ENET_ReadFrame when there is a received frame. */
|
||||
if (len != 0)
|
||||
{
|
||||
#if ETH_PAD_SIZE
|
||||
len += ETH_PAD_SIZE; /* allow room for Ethernet padding */
|
||||
#endif
|
||||
|
||||
/* We allocate a pbuf chain of pbufs from the pool. */
|
||||
p = pbuf_alloc(PBUF_RAW, len, PBUF_POOL);
|
||||
|
||||
if (p != NULL)
|
||||
{
|
||||
#if ETH_PAD_SIZE
|
||||
pbuf_header(p, -ETH_PAD_SIZE); /* drop the padding word */
|
||||
#endif
|
||||
if (p->next == 0) /* One-chain buffer.*/
|
||||
{
|
||||
ENET_ReadFrame(ethernetif->base, ðernetif->handle, p->payload, p->len);
|
||||
}
|
||||
else /* Multi-chain buffer.*/
|
||||
{
|
||||
uint8_t data_tmp[ENET_FRAME_MAX_FRAMELEN];
|
||||
uint32_t data_tmp_len = 0;
|
||||
|
||||
ENET_ReadFrame(ethernetif->base, ðernetif->handle, data_tmp, p->tot_len);
|
||||
|
||||
/* We iterate over the pbuf chain until we have read the entire
|
||||
* packet into the pbuf. */
|
||||
for (q = p; (q != NULL) && ((data_tmp_len + q->len) <= sizeof(data_tmp)); q = q->next)
|
||||
{
|
||||
/* Read enough bytes to fill this pbuf in the chain. The
|
||||
* available data in the pbuf is given by the q->len
|
||||
* variable. */
|
||||
memcpy(q->payload, &data_tmp[data_tmp_len], q->len);
|
||||
data_tmp_len += q->len;
|
||||
}
|
||||
}
|
||||
|
||||
MIB2_STATS_NETIF_ADD(netif, ifinoctets, p->tot_len);
|
||||
if (((u8_t *)p->payload)[0] & 1)
|
||||
{
|
||||
/* broadcast or multicast packet*/
|
||||
MIB2_STATS_NETIF_INC(netif, ifinnucastpkts);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* unicast packet*/
|
||||
MIB2_STATS_NETIF_INC(netif, ifinucastpkts);
|
||||
}
|
||||
#if ETH_PAD_SIZE
|
||||
pbuf_header(p, ETH_PAD_SIZE); /* reclaim the padding word */
|
||||
#endif
|
||||
|
||||
LINK_STATS_INC(link.recv);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* drop packet*/
|
||||
ENET_ReadFrame(ethernetif->base, ðernetif->handle, NULL, 0U);
|
||||
|
||||
LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_linkinput: Fail to allocate new memory space\n"));
|
||||
|
||||
LINK_STATS_INC(link.memerr);
|
||||
LINK_STATS_INC(link.drop);
|
||||
MIB2_STATS_NETIF_INC(netif, ifindiscards);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Update the received buffer when error happened. */
|
||||
if (status == kStatus_ENET_RxFrameError)
|
||||
{
|
||||
#if 0 && defined(FSL_FEATURE_SOC_ENET_COUNT) && (FSL_FEATURE_SOC_ENET_COUNT > 0) /* Error statisctics */
|
||||
enet_data_error_stats_t eErrStatic;
|
||||
/* Get the error information of the received g_frame. */
|
||||
ENET_GetRxErrBeforeReadFrame(ðernetif->handle, &eErrStatic);
|
||||
#endif
|
||||
|
||||
/* Update the receive buffer. */
|
||||
ENET_ReadFrame(ethernetif->base, ðernetif->handle, NULL, 0U);
|
||||
|
||||
LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_linkinput: RxFrameError\n"));
|
||||
|
||||
LINK_STATS_INC(link.drop);
|
||||
MIB2_STATS_NETIF_INC(netif, ifindiscards);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
err_t ethernetif_linkoutput(struct netif *netif, struct pbuf *p)
|
||||
{
|
||||
err_t result;
|
||||
struct ethernetif *ethernetif = netif->state;
|
||||
struct pbuf *q;
|
||||
unsigned char *pucBuffer;
|
||||
unsigned char *pucChar;
|
||||
|
||||
LWIP_ASSERT("Output packet buffer empty", p);
|
||||
|
||||
pucBuffer = enet_get_tx_buffer(ethernetif);
|
||||
if (pucBuffer == NULL)
|
||||
{
|
||||
return ERR_BUF;
|
||||
}
|
||||
|
||||
/* Initiate transfer. */
|
||||
|
||||
#if ETH_PAD_SIZE
|
||||
pbuf_header(p, -ETH_PAD_SIZE); /* drop the padding word */
|
||||
#endif
|
||||
|
||||
if (p->len == p->tot_len)
|
||||
{
|
||||
/* No pbuf chain, don't have to copy -> faster. */
|
||||
pucBuffer = (unsigned char *)p->payload;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* pbuf chain, copy into contiguous ucBuffer. */
|
||||
if (p->tot_len > ENET_FRAME_MAX_FRAMELEN)
|
||||
{
|
||||
return ERR_BUF;
|
||||
}
|
||||
else
|
||||
{
|
||||
pucChar = pucBuffer;
|
||||
|
||||
for (q = p; q != NULL; q = q->next)
|
||||
{
|
||||
/* Send the data from the pbuf to the interface, one pbuf at a
|
||||
time. The size of the data in each pbuf is kept in the ->len
|
||||
variable. */
|
||||
/* send data from(q->payload, q->len); */
|
||||
memcpy(pucChar, q->payload, q->len);
|
||||
pucChar += q->len;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Send frame. */
|
||||
result = enet_send_frame(ethernetif, pucBuffer, p->tot_len);
|
||||
|
||||
MIB2_STATS_NETIF_ADD(netif, ifoutoctets, p->tot_len);
|
||||
if (((u8_t *)p->payload)[0] & 1)
|
||||
{
|
||||
/* broadcast or multicast packet*/
|
||||
MIB2_STATS_NETIF_INC(netif, ifoutnucastpkts);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* unicast packet */
|
||||
MIB2_STATS_NETIF_INC(netif, ifoutucastpkts);
|
||||
}
|
||||
/* increase ifoutdiscards or ifouterrors on error */
|
||||
|
||||
#if ETH_PAD_SIZE
|
||||
pbuf_header(p, ETH_PAD_SIZE); /* reclaim the padding word */
|
||||
#endif
|
||||
|
||||
LINK_STATS_INC(link.xmit);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Should be called at the beginning of the program to set up the
|
||||
* first network interface. It calls the function ethernetif_init() to do the
|
||||
* actual setup of the hardware.
|
||||
*
|
||||
* This function should be passed as a parameter to netif_add().
|
||||
*
|
||||
* @param netif the lwip network interface structure for this ethernetif
|
||||
* @return ERR_OK if the loopif is initialized
|
||||
* ERR_MEM if private data couldn't be allocated
|
||||
* any other err_t on error
|
||||
*/
|
||||
err_t ethernetif0_init(struct netif *netif)
|
||||
{
|
||||
static struct ethernetif ethernetif_0;
|
||||
AT_NONCACHEABLE_SECTION_ALIGN(static enet_rx_bd_struct_t rxBuffDescrip_0[ENET_RXBD_NUM], FSL_ENET_BUFF_ALIGNMENT);
|
||||
AT_NONCACHEABLE_SECTION_ALIGN(static enet_tx_bd_struct_t txBuffDescrip_0[ENET_TXBD_NUM], FSL_ENET_BUFF_ALIGNMENT);
|
||||
SDK_ALIGN(static rx_buffer_t rxDataBuff_0[ENET_RXBD_NUM], FSL_ENET_BUFF_ALIGNMENT);
|
||||
SDK_ALIGN(static tx_buffer_t txDataBuff_0[ENET_TXBD_NUM], FSL_ENET_BUFF_ALIGNMENT);
|
||||
|
||||
ethernetif_0.RxBuffDescrip = &(rxBuffDescrip_0[0]);
|
||||
ethernetif_0.TxBuffDescrip = &(txBuffDescrip_0[0]);
|
||||
ethernetif_0.RxDataBuff = &(rxDataBuff_0[0]);
|
||||
ethernetif_0.TxDataBuff = &(txDataBuff_0[0]);
|
||||
|
||||
return ethernetif_init(netif, ðernetif_0, 0U, (ethernetif_config_t *)netif->state);
|
||||
}
|
||||
|
||||
#if defined(FSL_FEATURE_SOC_ENET_COUNT) && (FSL_FEATURE_SOC_ENET_COUNT > 1)
|
||||
/**
|
||||
* Should be called at the beginning of the program to set up the
|
||||
* second network interface. It calls the function ethernetif_init() to do the
|
||||
* actual setup of the hardware.
|
||||
*
|
||||
* This function should be passed as a parameter to netif_add().
|
||||
*
|
||||
* @param netif the lwip network interface structure for this ethernetif
|
||||
* @return ERR_OK if the loopif is initialized
|
||||
* ERR_MEM if private data couldn't be allocated
|
||||
* any other err_t on error
|
||||
*/
|
||||
err_t ethernetif1_init(struct netif *netif)
|
||||
{
|
||||
static struct ethernetif ethernetif_1;
|
||||
AT_NONCACHEABLE_SECTION_ALIGN(static enet_rx_bd_struct_t rxBuffDescrip_1[ENET_RXBD_NUM], FSL_ENET_BUFF_ALIGNMENT);
|
||||
AT_NONCACHEABLE_SECTION_ALIGN(static enet_tx_bd_struct_t txBuffDescrip_1[ENET_TXBD_NUM], FSL_ENET_BUFF_ALIGNMENT);
|
||||
SDK_ALIGN(static rx_buffer_t rxDataBuff_1[ENET_RXBD_NUM], FSL_ENET_BUFF_ALIGNMENT);
|
||||
SDK_ALIGN(static tx_buffer_t txDataBuff_1[ENET_TXBD_NUM], FSL_ENET_BUFF_ALIGNMENT);
|
||||
|
||||
ethernetif_1.RxBuffDescrip = &(rxBuffDescrip_1[0]);
|
||||
ethernetif_1.TxBuffDescrip = &(txBuffDescrip_1[0]);
|
||||
ethernetif_1.RxDataBuff = &(rxDataBuff_1[0]);
|
||||
ethernetif_1.TxDataBuff = &(txDataBuff_1[0]);
|
||||
|
||||
return ethernetif_init(netif, ðernetif_1, 1U, (ethernetif_config_t *)netif->state);
|
||||
}
|
||||
#endif /* FSL_FEATURE_SOC_*_ENET_COUNT */
|
||||
+972
@@ -0,0 +1,972 @@
|
||||
/*
|
||||
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the lwIP TCP/IP stack.
|
||||
*
|
||||
* Author: Adam Dunkels <adam@sics.se>
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2013-2016, Freescale Semiconductor, Inc.
|
||||
* Copyright 2016-2019 NXP
|
||||
* All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2021 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file enet_ethernetif_lpc.c
|
||||
* @brief ethernet drivers
|
||||
* @version 1.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2021.11.11
|
||||
*/
|
||||
|
||||
|
||||
#include "lwip/opt.h"
|
||||
#include "lwip/def.h"
|
||||
#include "lwip/mem.h"
|
||||
#include "lwip/pbuf.h"
|
||||
#include "lwip/stats.h"
|
||||
#include "lwip/snmp.h"
|
||||
#include "lwip/sys.h"
|
||||
#include "lwip/ethip6.h"
|
||||
#include "netif/etharp.h"
|
||||
#include "netif/ppp/pppoe.h"
|
||||
#include "lwip/igmp.h"
|
||||
#include "lwip/mld6.h"
|
||||
|
||||
//#if !NO_SYS
|
||||
//#include "FreeRTOS.h"
|
||||
//#include "event_groups.h"
|
||||
//#include "lwip/tcpip.h"
|
||||
//#endif /* !NO_SYS */
|
||||
|
||||
#include "enet_ethernetif.h"
|
||||
#include "enet_ethernetif_priv.h"
|
||||
|
||||
#include "fsl_enet.h"
|
||||
#include "fsl_phy.h"
|
||||
|
||||
//#if MEM_ALIGNMENT != FSL_ENET_BUFF_ALIGNMENT
|
||||
///* These two has to match for zero-copy functionality */
|
||||
//#error "MEM_ALIGNMENT != FSL_ENET_BUFF_ALIGNMENT"
|
||||
//#endif /* MEM_ALIGNMENT != FSL_ENET_BUFF_ALIGNMENT */
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
|
||||
/*!
|
||||
* @brief Used to wrap received data in a pbuf to be passed into lwIP
|
||||
* without copying.
|
||||
* Once last reference is released, RX descriptor will be returned to DMA.
|
||||
*/
|
||||
typedef struct rx_pbuf_wrapper
|
||||
{
|
||||
struct pbuf_custom p; /*!< Pbuf wrapper. Has to be first. */
|
||||
enet_rx_bd_struct_t* rxDesc; /*!< Descriptor holding the data. */
|
||||
struct ethernetif *ethernetif; /*!< Ethernet interface context data. */
|
||||
volatile bool ownedByLwip; /*!< If true, descriptor cannot be reused by DMA yet. */
|
||||
} rx_pbuf_wrapper_t;
|
||||
|
||||
/*!
|
||||
* @brief Helper struct to hold private data used to operate
|
||||
* your ethernet interface.
|
||||
*/
|
||||
struct ethernetif
|
||||
{
|
||||
ENET_Type *base;
|
||||
enet_handle_t handle;
|
||||
#if !NO_SYS
|
||||
EventGroupHandle_t enetTransmitAccessEvent;
|
||||
EventBits_t txFlag;
|
||||
#endif /* !NO_SYS */
|
||||
enet_rx_bd_struct_t *RxBuffDescrip;
|
||||
enet_tx_bd_struct_t *TxBuffDescrip;
|
||||
rx_buffer_t *RxDataBuff;
|
||||
volatile struct pbuf *txPbufs[ENET_TXBD_NUM];
|
||||
volatile uint8_t txIdx;
|
||||
volatile uint8_t txReleaseIdx;
|
||||
rx_pbuf_wrapper_t rxPbufs[ENET_RXBD_NUM];
|
||||
uint8_t rxIdx;
|
||||
const mem_range_t *non_dma_memory;
|
||||
};
|
||||
|
||||
static void ethernetif_tx_release(struct ethernetif *ethernetif);
|
||||
static void ethernetif_rx_release(struct pbuf *p);
|
||||
|
||||
/*******************************************************************************
|
||||
* Code
|
||||
******************************************************************************/
|
||||
|
||||
/**
|
||||
* Called from ENET ISR.
|
||||
*/
|
||||
static void ethernet_callback(ENET_Type *base, enet_handle_t *handle,
|
||||
enet_event_t event, uint8_t channel, void *param)
|
||||
#if NO_SYS
|
||||
{
|
||||
struct netif *netif = (struct netif *)param;
|
||||
struct ethernetif *ethernetif = netif->state;
|
||||
|
||||
if (event == kENET_TxIntEvent)
|
||||
{
|
||||
ethernetif_tx_release(ethernetif);
|
||||
}
|
||||
}
|
||||
#else
|
||||
{
|
||||
struct netif *netif = (struct netif *)param;
|
||||
struct ethernetif *ethernetif = netif->state;
|
||||
BaseType_t xResult;
|
||||
|
||||
switch (event)
|
||||
{
|
||||
case kENET_RxIntEvent:
|
||||
ethernetif_input(netif);
|
||||
break;
|
||||
case kENET_TxIntEvent:
|
||||
{
|
||||
portBASE_TYPE taskToWake = pdFALSE;
|
||||
|
||||
ethernetif_tx_release(ethernetif);
|
||||
|
||||
#ifdef __CA7_REV
|
||||
if (SystemGetIRQNestingLevel())
|
||||
#else
|
||||
if (__get_IPSR())
|
||||
#endif
|
||||
{
|
||||
xResult = xEventGroupSetBitsFromISR(
|
||||
ethernetif->enetTransmitAccessEvent,
|
||||
ethernetif->txFlag, &taskToWake);
|
||||
if ((pdPASS == xResult) && (pdTRUE == taskToWake))
|
||||
{
|
||||
portYIELD_FROM_ISR(taskToWake);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
xEventGroupSetBits(ethernetif->enetTransmitAccessEvent,
|
||||
ethernetif->txFlag);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif /* NO_SYS */
|
||||
|
||||
#if LWIP_IPV4 && LWIP_IGMP
|
||||
err_t ethernetif_igmp_mac_filter(struct netif *netif, const ip4_addr_t *group,
|
||||
enum netif_mac_filter_action action)
|
||||
{
|
||||
struct ethernetif *ethernetif = netif->state;
|
||||
err_t result;
|
||||
|
||||
switch (action)
|
||||
{
|
||||
case IGMP_ADD_MAC_FILTER:
|
||||
/* LPC ENET does not accept multicast selectively,
|
||||
* so all multicast has to be passed through. */
|
||||
ENET_AcceptAllMulticast(ethernetif->base);
|
||||
result = ERR_OK;
|
||||
break;
|
||||
case IGMP_DEL_MAC_FILTER:
|
||||
/*
|
||||
* Moves the ENET device from a multicast group.
|
||||
* Since we don't keep track of which multicast groups
|
||||
* are still to enabled, the call is commented out.
|
||||
*/
|
||||
/* ENET_RejectAllMulticast(ethernetif->base); */
|
||||
result = ERR_OK;
|
||||
break;
|
||||
default:
|
||||
result = ERR_IF;
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if LWIP_IPV6 && LWIP_IPV6_MLD
|
||||
err_t ethernetif_mld_mac_filter(struct netif *netif, const ip6_addr_t *group,
|
||||
enum netif_mac_filter_action action)
|
||||
{
|
||||
struct ethernetif *ethernetif = netif->state;
|
||||
err_t result;
|
||||
|
||||
switch (action)
|
||||
{
|
||||
case NETIF_ADD_MAC_FILTER:
|
||||
/* LPC ENET does not accept multicast selectively,
|
||||
* so all multicast has to be passed through. */
|
||||
ENET_AcceptAllMulticast(ethernetif->base);
|
||||
result = ERR_OK;
|
||||
break;
|
||||
case NETIF_DEL_MAC_FILTER:
|
||||
/*
|
||||
* Moves the ENET device from a multicast group.
|
||||
* Since we don't keep track of which multicast groups
|
||||
* are still to enabled, the call is commented out.
|
||||
*/
|
||||
/* ENET_RejectAllMulticast(ethernetif->base); */
|
||||
result = ERR_OK;
|
||||
break;
|
||||
default:
|
||||
result = ERR_IF;
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Gets the RX descriptor by its index.
|
||||
*/
|
||||
static inline enet_rx_bd_struct_t *ethernetif_get_rx_desc(
|
||||
struct ethernetif *ethernetif,
|
||||
uint32_t index)
|
||||
{
|
||||
return &(ethernetif->RxBuffDescrip[index]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the TX descriptor by its index.
|
||||
*/
|
||||
static inline enet_tx_bd_struct_t *ethernetif_get_tx_desc(
|
||||
struct ethernetif *ethernetif,
|
||||
uint32_t index)
|
||||
{
|
||||
return &(ethernetif->TxBuffDescrip[index]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes ENET driver.
|
||||
*/
|
||||
void ethernetif_enet_init(struct netif *netif, struct ethernetif *ethernetif,
|
||||
const ethernetif_config_t *ethernetifConfig)
|
||||
{
|
||||
enet_config_t config;
|
||||
uint32_t sysClock;
|
||||
enet_buffer_config_t buffCfg[ENET_RING_NUM];
|
||||
uint32_t rxBufferStartAddr[ENET_RXBD_NUM];
|
||||
uint32_t i;
|
||||
|
||||
/* calculate start addresses of all rx buffers */
|
||||
for (i = 0; i < ENET_RXBD_NUM; i++)
|
||||
{
|
||||
rxBufferStartAddr[i] = (uint32_t)&(ethernetif->RxDataBuff[i][ETH_PAD_SIZE]);
|
||||
}
|
||||
|
||||
/* prepare the buffer configuration. */
|
||||
buffCfg[0].rxRingLen = ENET_RXBD_NUM; /* The length of receive buffer descriptor ring. */
|
||||
buffCfg[0].txRingLen = ENET_TXBD_NUM; /* The length of transmit buffer descriptor ring. */
|
||||
buffCfg[0].txDescStartAddrAlign = ethernetif_get_tx_desc(ethernetif, 0U); /* Aligned transmit descriptor start address. */
|
||||
buffCfg[0].txDescTailAddrAlign = ethernetif_get_tx_desc(ethernetif, 0U); /* Aligned transmit descriptor tail address. */
|
||||
buffCfg[0].rxDescStartAddrAlign = ethernetif_get_rx_desc(ethernetif, 0U); /* Aligned receive descriptor start address. */
|
||||
buffCfg[0].rxDescTailAddrAlign = ethernetif_get_rx_desc(ethernetif, ENET_RXBD_NUM); /* Aligned receive descriptor tail address. */
|
||||
buffCfg[0].rxBufferStartAddr = rxBufferStartAddr; /* Start addresses of the rx buffers. */
|
||||
buffCfg[0].rxBuffSizeAlign = sizeof(rx_buffer_t); /* Aligned receive data buffer size. */
|
||||
|
||||
sysClock = CLOCK_GetFreq(ethernetifConfig->clockName);
|
||||
|
||||
LWIP_ASSERT("ethernetifConfig->non_dma_memory == NULL", (ethernetifConfig->non_dma_memory != NULL));
|
||||
ethernetif->non_dma_memory = ethernetifConfig->non_dma_memory;
|
||||
|
||||
ENET_GetDefaultConfig(&config);
|
||||
config.multiqueueCfg = NULL;
|
||||
|
||||
ethernetif_phy_init(ethernetif, ethernetifConfig, &config);
|
||||
|
||||
#if !NO_SYS
|
||||
/* Create the Event for transmit busy release trigger. */
|
||||
ethernetif->enetTransmitAccessEvent = xEventGroupCreate();
|
||||
ethernetif->txFlag = 0x1;
|
||||
#endif /* !NO_SYS */
|
||||
NVIC_SetPriority(ETHERNET_IRQn, ENET_PRIORITY);
|
||||
|
||||
ethernetif->txIdx = 0U;
|
||||
ethernetif->rxIdx = 0U;
|
||||
ethernetif->txReleaseIdx = 0U;
|
||||
|
||||
for (i = 0; i < ENET_RXBD_NUM; i++)
|
||||
{
|
||||
ethernetif->rxPbufs[i].p.custom_free_function = ethernetif_rx_release;
|
||||
ethernetif->rxPbufs[i].rxDesc = ðernetif->RxBuffDescrip[i];
|
||||
ethernetif->rxPbufs[i].ethernetif = ethernetif;
|
||||
ethernetif->rxPbufs[i].ownedByLwip = false;
|
||||
}
|
||||
|
||||
ENET_Init(ethernetif->base, &config, netif->hwaddr, sysClock);
|
||||
|
||||
#if defined(LPC54018_SERIES)
|
||||
/* Workaround for receive issue on lpc54018 */
|
||||
ethernetif->base->MAC_FRAME_FILTER |= ENET_MAC_FRAME_FILTER_RA_MASK;
|
||||
#endif
|
||||
|
||||
/* Create the handler. */
|
||||
#if NO_SYS
|
||||
ENET_EnableInterrupts(ethernetif->base, kENET_DmaTx);
|
||||
#else
|
||||
ENET_EnableInterrupts(ethernetif->base, kENET_DmaTx | kENET_DmaRx);
|
||||
#endif /* NO_SYS */
|
||||
ENET_CreateHandler(ethernetif->base, ðernetif->handle, &config,
|
||||
&buffCfg[0], ethernet_callback, netif);
|
||||
|
||||
ENET_DescriptorInit(ethernetif->base, &config, &buffCfg[0]);
|
||||
|
||||
/* Active TX/RX. */
|
||||
ENET_StartRxTx(ethernetif->base, 1, 1);
|
||||
}
|
||||
|
||||
ENET_Type **ethernetif_enet_ptr(struct ethernetif *ethernetif)
|
||||
{
|
||||
return &(ethernetif->base);
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the ENET instance index from its base address.
|
||||
*/
|
||||
static uint32_t ethernetif_get_enet_idx(ENET_Type *base)
|
||||
{
|
||||
static ENET_Type *const s_enetBases[] = ENET_BASE_PTRS;
|
||||
uint32_t instance;
|
||||
|
||||
for (instance = 0; instance < FSL_FEATURE_SOC_LPC_ENET_COUNT; instance++)
|
||||
{
|
||||
if (s_enetBases[instance] == base)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
LWIP_ASSERT("Cannot find ENET instance index from its base address.",
|
||||
instance < FSL_FEATURE_SOC_LPC_ENET_COUNT);
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends (part of) a frame via ENET.
|
||||
* TODO: Since ENET_SendFrame() could not be used, some functionality it does
|
||||
* is missing here for now (channel selection depending on AVB content,
|
||||
* timestamping.
|
||||
*/
|
||||
static void ethernetif_send_buffer(struct ethernetif *ethernetif,
|
||||
unsigned char *data,
|
||||
const uint32_t length,
|
||||
struct pbuf *p_to_release,
|
||||
enet_desc_flag flag)
|
||||
{
|
||||
static const IRQn_Type s_enetIrqId[] = ENET_IRQS;
|
||||
enet_tx_bd_struct_t *txDesc = ethernetif_get_tx_desc(ethernetif,
|
||||
ethernetif->txIdx);
|
||||
ethernetif->txPbufs[ethernetif->txIdx] = p_to_release;
|
||||
ethernetif->txIdx = (ethernetif->txIdx + 1) % ENET_TXBD_NUM;
|
||||
|
||||
/* Prepare the descriptor for transmit. */
|
||||
txDesc->buff1Addr = (uint32_t)data;
|
||||
txDesc->buff2Addr = (uint32_t)NULL;
|
||||
txDesc->buffLen =
|
||||
ENET_TXDESCRIP_RD_BL1(length) | ENET_TXDESCRIP_RD_IOC_MASK;
|
||||
|
||||
txDesc->controlStat =
|
||||
ENET_TXDESCRIP_RD_FL(length) | ENET_TXDESCRIP_RD_LDFD(flag);
|
||||
if ((flag & kENET_FirstFlagOnly) == 0)
|
||||
{
|
||||
/*
|
||||
* Submit to DMA if not the first descriptor in chain.
|
||||
* All the descriptors have to be prepared before the first one
|
||||
* is flagged for DMA and transfer starts. ENET could output invalid
|
||||
* frames otherwise (the exception is Store and Forward mode, where
|
||||
* delays between preparing of descriptors does not matter).
|
||||
*/
|
||||
txDesc->controlStat |= ENET_TXDESCRIP_RD_OWN_MASK;
|
||||
}
|
||||
|
||||
enet_tx_bd_ring_t *txBdRing = (enet_tx_bd_ring_t *)
|
||||
ðernetif->handle.txBdRing[0];
|
||||
|
||||
/*
|
||||
* Increment txDescUsed.
|
||||
* Without this, callback would not fire from ENET ISR on finished TX.
|
||||
* This is kind of a hack. Alternative could be to define
|
||||
* void ETHERNET_DriverIRQHandler(void) and handle IRQs completely
|
||||
* in this file.
|
||||
*/
|
||||
DisableIRQ(s_enetIrqId[ethernetif_get_enet_idx(ethernetif->base)]);
|
||||
txBdRing->txDescUsed++;
|
||||
EnableIRQ(s_enetIrqId[ethernetif_get_enet_idx(ethernetif->base)]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reclaims exactly one TX descriptor after its data has been sent out.
|
||||
* Then the descriptor can be used by application to prepare next data to send.
|
||||
*/
|
||||
static void ethernetif_tx_release(struct ethernetif *ethernetif)
|
||||
{
|
||||
LWIP_ASSERT("Attempt to release more TX buffers than acquired.",
|
||||
ethernetif->txIdx != ethernetif->txReleaseIdx);
|
||||
enet_tx_bd_struct_t *txDesc
|
||||
= ðernetif->TxBuffDescrip[ethernetif->txReleaseIdx];
|
||||
LWIP_ASSERT("TX buffer still owned by DMA.",
|
||||
!ENET_IsTxDescriptorDmaOwn(txDesc));
|
||||
|
||||
struct pbuf *p = (struct pbuf *)
|
||||
ethernetif->txPbufs[ethernetif->txReleaseIdx];
|
||||
if (p != NULL)
|
||||
{
|
||||
#if ETH_PAD_SIZE
|
||||
/* Reclaim the padding, force because it may be REF pbuf. */
|
||||
pbuf_header_force(p, ETH_PAD_SIZE);
|
||||
#endif
|
||||
|
||||
#if NO_SYS
|
||||
#if defined(LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT) && LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT
|
||||
pbuf_free(p);
|
||||
#else
|
||||
#error "Bare metal requires LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT=1 because pbuf_free() is being called from an ISR"
|
||||
#endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */
|
||||
#else
|
||||
if (pbuf_free_callback(p) != ERR_OK)
|
||||
{
|
||||
#if defined(LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT) && LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT
|
||||
pbuf_free(p);
|
||||
#else
|
||||
LWIP_ASSERT("Failed to enqueue pbuf deallocation on tcpip_thread",
|
||||
0);
|
||||
#endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */
|
||||
}
|
||||
#endif /* NO_SYS */
|
||||
|
||||
ethernetif->txPbufs[ethernetif->txReleaseIdx] = NULL;
|
||||
}
|
||||
|
||||
ethernetif->txReleaseIdx = (ethernetif->txReleaseIdx + 1) % ENET_TXBD_NUM;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reclaims RX descriptor which holds the p's buffer after p is no longer used
|
||||
* by the application / lwIP. The DMA can receive new data into
|
||||
* the descriptor's buffer then.
|
||||
* Note that RX buffers may be freed by lwIP out of the order in which they were
|
||||
* passed to lwIP. Therefore there may be spaces between the RX descriptors
|
||||
* flagged as owned by DMA and DMA could still wait until it's actual position
|
||||
* is released.
|
||||
*/
|
||||
static void ethernetif_rx_release(struct pbuf *p)
|
||||
{
|
||||
SYS_ARCH_DECL_PROTECT(old_level);
|
||||
rx_pbuf_wrapper_t *wrapper = (rx_pbuf_wrapper_t *)p;
|
||||
#if NO_SYS
|
||||
bool intEnable = false;
|
||||
#else
|
||||
bool intEnable = true;
|
||||
#endif /* NO_SYS */
|
||||
|
||||
SYS_ARCH_PROTECT(old_level);
|
||||
|
||||
wrapper->ownedByLwip = false;
|
||||
|
||||
/* Update the receive buffer descriptor. */
|
||||
ENET_UpdateRxDescriptor(wrapper->rxDesc, NULL, NULL, intEnable, false);
|
||||
ENET_UpdateRxDescriptorTail(wrapper->ethernetif->base, 0U,
|
||||
(uint32_t)ethernetif_get_rx_desc(wrapper->ethernetif, ENET_RXBD_NUM));
|
||||
|
||||
SYS_ARCH_UNPROTECT(old_level);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the length of a received frame (if there is some).
|
||||
*/
|
||||
static status_t ethernetif_get_rx_frame_size(struct ethernetif *ethernetif,
|
||||
uint32_t *length)
|
||||
{
|
||||
uint8_t index = ethernetif->rxIdx;
|
||||
enet_rx_bd_struct_t *rxDesc;
|
||||
uint32_t rxControl;
|
||||
|
||||
/* Reset the length to zero. */
|
||||
*length = 0;
|
||||
|
||||
do
|
||||
{
|
||||
rxDesc = ethernetif_get_rx_desc(ethernetif, index);
|
||||
rxControl = ENET_GetRxDescriptor(rxDesc);
|
||||
|
||||
if ((rxControl & ENET_RXDESCRIP_WR_OWN_MASK)
|
||||
|| (ethernetif->rxPbufs[index].ownedByLwip))
|
||||
{
|
||||
/*
|
||||
* Buffer descriptor is owned by DMA or lwIP.
|
||||
* We haven't received any complete frame yet.
|
||||
*/
|
||||
return kStatus_ENET_RxFrameEmpty;
|
||||
}
|
||||
|
||||
/* Application owns the buffer descriptor. */
|
||||
if (rxControl & ENET_RXDESCRIP_WR_LD_MASK)
|
||||
{
|
||||
/* It's last descriptor of a frame, get its status or length. */
|
||||
if (rxControl & ENET_RXDESCRIP_WR_ERRSUM_MASK)
|
||||
{
|
||||
return kStatus_ENET_RxFrameError;
|
||||
}
|
||||
else
|
||||
{
|
||||
*length = rxControl & ENET_RXDESCRIP_WR_PACKETLEN_MASK;
|
||||
return kStatus_Success;
|
||||
}
|
||||
}
|
||||
|
||||
index = (index + 1U) % ENET_RXBD_NUM;
|
||||
} while (index != ethernetif->rxIdx);
|
||||
|
||||
/*
|
||||
* All descriptors have data but the end of the frame not detected.
|
||||
*/
|
||||
return kStatus_ENET_RxFrameError;
|
||||
}
|
||||
|
||||
/**
|
||||
* Drops (releases) receive descriptors until the last one of a frame is reached
|
||||
* or drops entire descriptor ring when all descriptors have data but end
|
||||
* of the frame not detected among them.
|
||||
* Function can be called only after ethernetif_get_rx_frame_size() indicates
|
||||
* that there actually is a frame error or a received frame.
|
||||
*/
|
||||
static void ethernetif_drop_frame(struct ethernetif *ethernetif)
|
||||
{
|
||||
#if NO_SYS
|
||||
bool intEnable = false;
|
||||
#else
|
||||
bool intEnable = true;
|
||||
#endif /* NO_SYS */
|
||||
|
||||
enet_rx_bd_struct_t *rxDesc;
|
||||
uint8_t index = ethernetif->rxIdx;
|
||||
uint32_t rxControl;
|
||||
|
||||
do
|
||||
{
|
||||
rxDesc = ethernetif_get_rx_desc(ethernetif, ethernetif->rxIdx);
|
||||
ethernetif->rxIdx = (ethernetif->rxIdx + 1U) % ENET_RXBD_NUM;
|
||||
rxControl = ENET_GetRxDescriptor(rxDesc);
|
||||
|
||||
/* Update the receive buffer descriptor. */
|
||||
ENET_UpdateRxDescriptor(rxDesc, NULL, NULL, intEnable, false);
|
||||
|
||||
/* Find the last buffer descriptor for the frame. */
|
||||
if (rxControl & ENET_RXDESCRIP_WR_LD_MASK)
|
||||
{
|
||||
break;
|
||||
}
|
||||
} while (ethernetif->rxIdx != index);
|
||||
|
||||
ENET_UpdateRxDescriptorTail(ethernetif->base, 0U,
|
||||
(uint32_t)ethernetif_get_rx_desc(ethernetif, ENET_RXBD_NUM));
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads a received frame - wraps its descriptor buffer(s) into a pbuf
|
||||
* or a pbuf chain, flag descriptors as owned by lwIP and returns the pbuf.
|
||||
* The descriptors are returned to DMA only after the returned pbuf is released.
|
||||
* Function can be called only after ethernetif_get_rx_frame_size() indicates
|
||||
* that there actually is a received frame.
|
||||
*/
|
||||
static struct pbuf *ethernetif_read_frame(struct ethernetif *ethernetif,
|
||||
uint32_t length)
|
||||
{
|
||||
rx_pbuf_wrapper_t *wrapper;
|
||||
enet_rx_bd_struct_t *rxDesc;
|
||||
uint32_t rxControl;
|
||||
uint32_t len = 0;
|
||||
struct pbuf *p = NULL;
|
||||
struct pbuf *q = NULL;
|
||||
|
||||
do
|
||||
{
|
||||
wrapper = ðernetif->rxPbufs[ethernetif->rxIdx];
|
||||
wrapper->ownedByLwip = true;
|
||||
ethernetif->rxIdx = (ethernetif->rxIdx + 1U) % ENET_RXBD_NUM;
|
||||
|
||||
rxDesc = wrapper->rxDesc;
|
||||
rxControl = ENET_GetRxDescriptor(rxDesc);
|
||||
|
||||
len = (rxControl & ENET_RXDESCRIP_WR_PACKETLEN_MASK);
|
||||
|
||||
/* Wrap the receive buffer in pbuf. */
|
||||
if (p == NULL)
|
||||
{
|
||||
p = pbuf_alloced_custom(PBUF_RAW, len, PBUF_REF, &wrapper->p,
|
||||
(void *)rxDesc->buff1Addr, len);
|
||||
LWIP_ASSERT("pbuf_alloced_custom() failed", p);
|
||||
|
||||
#if ETH_PAD_SIZE
|
||||
/* Add the padding header, force because it is a REF type buffer. */
|
||||
pbuf_header_force(p, ETH_PAD_SIZE);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
q = pbuf_alloced_custom(PBUF_RAW, len, PBUF_REF, &wrapper->p,
|
||||
(void *)rxDesc->buff1Addr, len);
|
||||
LWIP_ASSERT("pbuf_alloced_custom() failed", q);
|
||||
|
||||
pbuf_cat(p, q);
|
||||
}
|
||||
} while (((rxControl & ENET_RXDESCRIP_WR_LD_MASK) == 0U)
|
||||
&& (p->tot_len < length));
|
||||
|
||||
MIB2_STATS_NETIF_ADD(netif, ifinoctets, p->tot_len);
|
||||
if (((u8_t *)p->payload)[0] & 1)
|
||||
{
|
||||
/* broadcast or multicast packet */
|
||||
MIB2_STATS_NETIF_INC(netif, ifinnucastpkts);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* unicast packet */
|
||||
MIB2_STATS_NETIF_INC(netif, ifinucastpkts);
|
||||
}
|
||||
|
||||
LINK_STATS_INC(link.recv);
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to read a frame from ENET and returns it wrapped in a pbuf
|
||||
* or returns NULL when no frame is received. Discards invalid frames.
|
||||
*/
|
||||
struct pbuf *ethernetif_linkinput(struct netif *netif)
|
||||
{
|
||||
struct ethernetif *ethernetif = netif->state;
|
||||
struct pbuf *p = NULL;
|
||||
uint32_t len;
|
||||
status_t status;
|
||||
|
||||
/* Obtain the size of the packet and put it into the "len" variable. */
|
||||
status = ethernetif_get_rx_frame_size(ethernetif, &len);
|
||||
|
||||
if (status == kStatus_Success)
|
||||
{
|
||||
p = ethernetif_read_frame(ethernetif, len);
|
||||
|
||||
if (p == NULL)
|
||||
{
|
||||
/* Could not initialise wrapper pbuf(s) - drop the frame. */
|
||||
ethernetif_drop_frame(ethernetif);
|
||||
|
||||
LWIP_DEBUGF(NETIF_DEBUG,
|
||||
("ethernetif_linkinput: Fail to allocate new memory space\n"));
|
||||
|
||||
LINK_STATS_INC(link.memerr);
|
||||
LINK_STATS_INC(link.drop);
|
||||
MIB2_STATS_NETIF_INC(netif, ifindiscards);
|
||||
}
|
||||
}
|
||||
else if (status == kStatus_ENET_RxFrameError)
|
||||
{
|
||||
/* Update the received buffer when error happened. */
|
||||
ethernetif_drop_frame(ethernetif);
|
||||
|
||||
LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_linkinput: RxFrameError\n"));
|
||||
|
||||
LINK_STATS_INC(link.drop);
|
||||
MIB2_STATS_NETIF_INC(netif, ifindiscards);
|
||||
}
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of TX descriptors which could be used by lwIP/application
|
||||
* to put new TX data into.
|
||||
*
|
||||
* The max number of free descriptors is (ENET_TXBD_NUM - 1), that is when
|
||||
* ethernetif->txReleaseIdx == ethernetif->txIdx. Having the capacity decreased
|
||||
* by one allows to avoid locking: txReleaseIdx is advanced only from ISR
|
||||
* and txIdx from tcpip_thread/main loop. Should we use full capacity and have
|
||||
* some variable to indicate between the "all buffers are free" vs. "all buffers
|
||||
* are used" situation, it would be manipulated from two contexts hence locking
|
||||
* would be needed.
|
||||
*/
|
||||
static inline int ethernetif_avail_tx_descs(struct ethernetif *ethernetif)
|
||||
{
|
||||
return (ethernetif->txReleaseIdx + ENET_TXBD_NUM - 1 - ethernetif->txIdx)
|
||||
% ENET_TXBD_NUM;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to output a frame from ENET. The function avoids copying of
|
||||
* p's payload when possible. In such situation it increases p's reference count
|
||||
* and decreases it (and possibly releases p) after the payload is sent.
|
||||
*/
|
||||
err_t ethernetif_linkoutput(struct netif *netif, struct pbuf *p)
|
||||
{
|
||||
struct ethernetif *ethernetif = netif->state;
|
||||
struct pbuf *q;
|
||||
struct pbuf *pbuf_to_free = NULL;
|
||||
struct pbuf *p_copy;
|
||||
uint16_t clen;
|
||||
bool copy = false;
|
||||
const mem_range_t *non_dma_memory;
|
||||
uint8_t *dst;
|
||||
uint32_t cnt = 0;
|
||||
uint8_t first_idx;
|
||||
uint32_t tail_address;
|
||||
|
||||
LWIP_ASSERT("Output packet buffer empty", p);
|
||||
|
||||
if ((p->tot_len - ETH_PAD_SIZE) > ENET_FRAME_MAX_FRAMELEN)
|
||||
{
|
||||
return ERR_BUF;
|
||||
}
|
||||
|
||||
clen = pbuf_clen(p);
|
||||
|
||||
/* Check if relocation is needed */
|
||||
|
||||
if (clen > (ENET_TXBD_NUM - 1))
|
||||
{
|
||||
/* Pbuf chain is too long to be prepared for DMA at once. */
|
||||
copy = true;
|
||||
}
|
||||
|
||||
for (q = p; (q != NULL) && !copy; q = q->next)
|
||||
{
|
||||
/*
|
||||
* Check if payload is aligned is not desired: lwIP creates RAM pbufs
|
||||
* in a way that the data coming after the headers are aligned, but not
|
||||
* the beginning of the ethernet header. LPC ENET DMA will read from
|
||||
* the aligned address, which is ok, because there is additional space
|
||||
* before the headers to make up for alignment - so DMA will not read
|
||||
* from invalid address or unrelated data.
|
||||
*/
|
||||
|
||||
/* Check payload address is usable by ENET DMA */
|
||||
for (non_dma_memory = ethernetif->non_dma_memory;
|
||||
(non_dma_memory->start != 0U)
|
||||
|| (non_dma_memory->end != 0U); non_dma_memory++)
|
||||
{
|
||||
if ((q->payload >= (void *) non_dma_memory->start)
|
||||
&& (q->payload < (void *) non_dma_memory->end))
|
||||
{
|
||||
copy = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (copy)
|
||||
{
|
||||
/* Pbuf needs to be copied. */
|
||||
|
||||
p_copy = pbuf_alloc(PBUF_RAW, (uint16_t) p->tot_len, PBUF_POOL);
|
||||
if (p_copy == NULL)
|
||||
{
|
||||
return ERR_MEM;
|
||||
}
|
||||
|
||||
dst = (uint8_t *) p_copy->payload;
|
||||
for (q = p; q != NULL; q = q->next)
|
||||
{
|
||||
LWIP_ASSERT("Copied bytes would exceed p->tot_len",
|
||||
(q->len + dst - (uint8_t *) p_copy->payload) <= p->tot_len);
|
||||
memcpy(dst, (uint8_t *)q->payload, q->len);
|
||||
dst += q->len;
|
||||
}
|
||||
LWIP_ASSERT("Copied bytes != p->tot_len",
|
||||
(dst - (uint8_t *) p_copy->payload) == p->tot_len);
|
||||
p_copy->len = p_copy->tot_len = p->tot_len;
|
||||
|
||||
p = p_copy;
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* Increase reference count so p is released only after it is sent.
|
||||
* For copied pbuf, ref is already 1 after pbuf_alloc().
|
||||
*/
|
||||
pbuf_ref(p);
|
||||
}
|
||||
|
||||
/*
|
||||
* Wait until the sufficient number of descriptors are available,
|
||||
* as we have to start the transfer of the first buffer only
|
||||
* after all buffers in chain are prepared.
|
||||
*/
|
||||
while (ethernetif_avail_tx_descs(ethernetif) < clen)
|
||||
{
|
||||
#if !NO_SYS
|
||||
xEventGroupWaitBits(ethernetif->enetTransmitAccessEvent,
|
||||
ethernetif->txFlag, pdTRUE, (BaseType_t) false,
|
||||
portMAX_DELAY);
|
||||
#endif /* !NO_SYS */
|
||||
cnt++;
|
||||
if (cnt >= ENET_TIMEOUT)
|
||||
{
|
||||
return ERR_TIMEOUT;
|
||||
}
|
||||
}
|
||||
|
||||
#if ETH_PAD_SIZE
|
||||
/* Drop the padding. */
|
||||
pbuf_header(p, -ETH_PAD_SIZE);
|
||||
#endif
|
||||
|
||||
/* Initiate transfer. */
|
||||
|
||||
first_idx = ethernetif->txIdx;
|
||||
|
||||
for (q = p; q != NULL; q = q->next)
|
||||
{
|
||||
enet_desc_flag flag = kENET_MiddleFlag;
|
||||
pbuf_to_free = NULL;
|
||||
|
||||
if (q == p)
|
||||
{
|
||||
flag |= kENET_FirstFlagOnly;
|
||||
}
|
||||
|
||||
if (q->next == NULL)
|
||||
{
|
||||
flag |= kENET_LastFlagOnly;
|
||||
|
||||
/* On last TX interrupt, free pbuf chain. */
|
||||
pbuf_to_free = p;
|
||||
}
|
||||
|
||||
ethernetif_send_buffer(ethernetif, q->payload, q->len, pbuf_to_free,
|
||||
flag);
|
||||
}
|
||||
|
||||
/* All pbufs from chain are prepared, allow DMA to access the first one. */
|
||||
ethernetif_get_tx_desc(ethernetif, first_idx)->controlStat |=
|
||||
ENET_TXDESCRIP_RD_OWN_MASK;
|
||||
|
||||
/* Update the transmit tail address. */
|
||||
if (ethernetif->txIdx == 0U)
|
||||
{
|
||||
tail_address = (uint32_t)ethernetif_get_tx_desc(ethernetif,
|
||||
ENET_TXBD_NUM);
|
||||
}
|
||||
else
|
||||
{
|
||||
tail_address = (uint32_t)ethernetif_get_tx_desc(ethernetif,
|
||||
ethernetif->txIdx);
|
||||
}
|
||||
ENET_UpdateTxDescriptorTail(ethernetif->base, 0, tail_address);
|
||||
|
||||
MIB2_STATS_NETIF_ADD(netif, ifoutoctets, p->tot_len);
|
||||
if (((uint8_t *)p->payload)[0] & 1)
|
||||
{
|
||||
/* broadcast or multicast packet */
|
||||
MIB2_STATS_NETIF_INC(netif, ifoutnucastpkts);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* unicast packet */
|
||||
MIB2_STATS_NETIF_INC(netif, ifoutucastpkts);
|
||||
}
|
||||
LINK_STATS_INC(link.xmit);
|
||||
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Should be called at the beginning of the program to set up the
|
||||
* first network interface. It calls the function ethernetif_init() to do the
|
||||
* actual setup of the hardware.
|
||||
*
|
||||
* This function should be passed as a parameter to netif_add().
|
||||
*
|
||||
* @param netif the lwip network interface structure for this ethernetif
|
||||
* @return ERR_OK if the loopif is initialized
|
||||
* ERR_MEM if private data couldn't be allocated
|
||||
* any other err_t on error
|
||||
*/
|
||||
err_t ethernetif0_init(struct netif *netif)
|
||||
{
|
||||
static struct ethernetif ethernetif_0;
|
||||
AT_NONCACHEABLE_SECTION_ALIGN(static enet_rx_bd_struct_t rxBuffDescrip_0[ENET_RXBD_NUM], FSL_ENET_BUFF_ALIGNMENT);
|
||||
AT_NONCACHEABLE_SECTION_ALIGN(static enet_tx_bd_struct_t txBuffDescrip_0[ENET_TXBD_NUM], FSL_ENET_BUFF_ALIGNMENT);
|
||||
SDK_ALIGN(static rx_buffer_t rxDataBuff_0[ENET_RXBD_NUM], FSL_ENET_BUFF_ALIGNMENT);
|
||||
|
||||
ethernetif_0.RxBuffDescrip = &(rxBuffDescrip_0[0]);
|
||||
ethernetif_0.TxBuffDescrip = &(txBuffDescrip_0[0]);
|
||||
ethernetif_0.RxDataBuff = &(rxDataBuff_0[0]);
|
||||
|
||||
return ethernetif_init(netif, ðernetif_0, 0U, (ethernetif_config_t *)netif->state);
|
||||
}
|
||||
|
||||
#if defined(FSL_FEATURE_SOC_LPC_ENET_COUNT) && (FSL_FEATURE_SOC_LPC_ENET_COUNT > 1)
|
||||
/**
|
||||
* Should be called at the beginning of the program to set up the
|
||||
* second network interface. It calls the function ethernetif_init() to do the
|
||||
* actual setup of the hardware.
|
||||
*
|
||||
* This function should be passed as a parameter to netif_add().
|
||||
*
|
||||
* @param netif the lwip network interface structure for this ethernetif
|
||||
* @return ERR_OK if the loopif is initialized
|
||||
* ERR_MEM if private data couldn't be allocated
|
||||
* any other err_t on error
|
||||
*/
|
||||
err_t ethernetif1_init(struct netif *netif)
|
||||
{
|
||||
static struct ethernetif ethernetif_1;
|
||||
AT_NONCACHEABLE_SECTION_ALIGN(static enet_rx_bd_struct_t rxBuffDescrip_1[ENET_RXBD_NUM], FSL_ENET_BUFF_ALIGNMENT);
|
||||
AT_NONCACHEABLE_SECTION_ALIGN(static enet_tx_bd_struct_t txBuffDescrip_1[ENET_TXBD_NUM], FSL_ENET_BUFF_ALIGNMENT);
|
||||
SDK_ALIGN(static rx_buffer_t rxDataBuff_1[ENET_RXBD_NUM], FSL_ENET_BUFF_ALIGNMENT);
|
||||
|
||||
ethernetif_1.RxBuffDescrip = &(rxBuffDescrip_1[0]);
|
||||
ethernetif_1.TxBuffDescrip = &(txBuffDescrip_1[0]);
|
||||
ethernetif_1.RxDataBuff = &(rxDataBuff_1[0]);
|
||||
|
||||
return ethernetif_init(netif, ðernetif_1, 1U, (ethernetif_config_t *)netif->state);
|
||||
}
|
||||
#endif /* FSL_FEATURE_SOC_*_ENET_COUNT */
|
||||
+94
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
* Copyright 2019 NXP
|
||||
* All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2021 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file enet_ethernetif_priv.h
|
||||
* @brief ethernet drivers
|
||||
* @version 1.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2021.11.11
|
||||
*/
|
||||
|
||||
|
||||
#ifndef ENET_ETHERNETIF_PRIV_H
|
||||
#define ENET_ETHERNETIF_PRIV_H
|
||||
|
||||
#include "lwip/err.h"
|
||||
|
||||
struct ethernetif;
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
err_t ethernetif_init(struct netif *netif, struct ethernetif *ethernetif,
|
||||
const uint8_t enetIdx,
|
||||
const ethernetif_config_t *ethernetifConfig);
|
||||
|
||||
void ethernetif_enet_init(struct netif *netif, struct ethernetif *ethernetif,
|
||||
const ethernetif_config_t *ethernetifConfig);
|
||||
|
||||
void ethernetif_phy_init(struct ethernetif *ethernetif,
|
||||
const ethernetif_config_t *ethernetifConfig,
|
||||
enet_config_t *config);
|
||||
|
||||
ENET_Type **ethernetif_enet_ptr(struct ethernetif *ethernetif);
|
||||
|
||||
#if LWIP_IPV4 && LWIP_IGMP
|
||||
err_t ethernetif_igmp_mac_filter(struct netif *netif, const ip4_addr_t *group,
|
||||
enum netif_mac_filter_action action);
|
||||
#endif
|
||||
|
||||
#if LWIP_IPV6 && LWIP_IPV6_MLD
|
||||
err_t ethernetif_mld_mac_filter(struct netif *netif, const ip6_addr_t *group,
|
||||
enum netif_mac_filter_action action);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Should allocate a pbuf and transfer the bytes of the incoming
|
||||
* packet from the interface into the pbuf.
|
||||
*
|
||||
* @param netif the lwip network interface structure for this ethernetif
|
||||
* @return a pbuf filled with the received packet (including MAC header)
|
||||
* NULL on memory error
|
||||
*/
|
||||
struct pbuf *ethernetif_linkinput(struct netif *netif);
|
||||
|
||||
/**
|
||||
* This function should do the actual transmission of the packet. The packet is
|
||||
* contained in the pbuf that is passed to the function. This pbuf
|
||||
* might be chained.
|
||||
*
|
||||
* @param netif the lwip network interface structure for this ethernetif
|
||||
* @param p the MAC packet to send (e.g. IP packet including MAC addresses and type)
|
||||
* @return ERR_OK if the packet could be sent
|
||||
* an err_t value if the packet couldn't be sent
|
||||
*
|
||||
* @note Returning ERR_MEM here if a DMA queue of your MAC is full can lead to
|
||||
* strange results. You might consider waiting for space in the DMA queue
|
||||
* to become available since the stack doesn't retry to send a packet
|
||||
* dropped because of memory failure (except for the TCP timers).
|
||||
*/
|
||||
err_t ethernetif_linkoutput(struct netif *netif, struct pbuf *p);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* ENET_ETHERNETIF_PRIV_H */
|
||||
+75
@@ -0,0 +1,75 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file connect_ethernet.h
|
||||
* @author MCD Application Team
|
||||
* @version V1.0.0
|
||||
* @date 31-October-2011
|
||||
* @brief STM32F4x7 Ethernet hardware configuration.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
|
||||
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
|
||||
* TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
|
||||
* FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
|
||||
* CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2011 STMicroelectronics</center></h2>
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2020 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file connect_ethernet.h
|
||||
* @brief Adapted network software protocol stack and hardware operation functions
|
||||
* @version 1.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2021-12-7
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __ETH_BSP_H
|
||||
#define __ETH_BSP_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
|
||||
|
||||
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
/* Exported constants --------------------------------------------------------*/
|
||||
|
||||
|
||||
/* Exported macro ------------------------------------------------------------*/
|
||||
|
||||
#ifndef sourceClock
|
||||
#define sourceClock CLOCK_GetFreq(kCLOCK_CoreSysClk)
|
||||
#endif
|
||||
|
||||
/* Exported functions ------------------------------------------------------- */
|
||||
|
||||
void enet_delay(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __STM32F4x7_ETH_BSP_H */
|
||||
|
||||
|
||||
/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
|
||||
Reference in New Issue
Block a user