Other Parts Discussed in Thread: RM46L852, HALCOGEN
Tool/software:
I have DP83848 connected to RM46L852 in RMII Mode. Connections are as follows :
RM46 MDIO - DP83848 MDIO
RM46 MDC - DP83848 MDC
RM46 RMII_REFCLK_50MHZ - DP83848 OSCIN
RM46 CRS_DV - DP83848 CRS_DV
RM46 TX_EN - DP83848 TXEN
RM46 TX1 - DP83848 TX1
RM46 TX0 - DP83848TX0
RM46 RX1 - DP83848 RX1
RM46 RX0 - DP83848 RX0
CLOCK is given externaly through 3.3V External Oscillator connected to X1 of DP83848 as well as RMII_REFCLK of RM46L852.
I am sharing the Code of sys_main.c and emac.c, halcogen settings.
Problem I am facing so much of noise 50MHz corrupts 3.3V and Gnd as well. MDIO communication happens properly. Transmit happens and all buffer descriptor will get set but receive descriptors will not set properly. RXGOODFRAMES gets reflect in registors of EMC. (I enabled Loopback in DP83848 through Bit 0x00 to 0x6100)
In halcogen, in Driver Enable - EMAC Driver, C0_TX_INT, C0_RX_INT, DISABLE - ENABLE MII, DISABLE - ENABLE LOOPBACK , OTHERS IN ENABLE CONDITION .
Please help and I am stuck in this from last few weeks.
GND NOISE OF 20ns - 50MHz
3v3 Vcc of 20ns - 50MHz
/** @file sys_main.c
* @brief Application main file
* @date 11-Dec-2018
* @version 04.07.01
*
* This file contains an empty main function,
* which can be used for the application.
*/
/*
* Copyright (C) 2009-2018 Texas Instruments Incorporated - www.ti.com
*
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 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.
*
* Neither the name of Texas Instruments Incorporated nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "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 COPYRIGHT
* OWNER OR CONTRIBUTORS 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.
*
*/
/* USER CODE BEGIN (0) */
/* USER CODE END */
/* Include Files */
#include "sys_common.h"
/* USER CODE BEGIN (1) */
#include "emac.h"
#include "hw_reg_access.h"
/* USER CODE END */
/** @fn void main(void)
* @brief Application main function
* @note This function is empty by default.
*
* This function is called after startup.
* The user can use this function to implement the application.
*/
/* USER CODE BEGIN (2) */
uint8 emacAddress[6U] = {0x00U, 0x08U, 0xEEU, 0x03U, 0xA6U, 0x6CU};
uint32 emacPhyAddress = 1U;
extern hdkif_t hdkif_data[1];
volatile emac_rx_bd_t *curr_bd, *curr_tail, *last_bd, *processed_bd;
rxch_t *rxch_int, *rxch_int_temp;
pbuf_t pack[5];
static uint8 data[5][100];
uint32 size1 = 470,size2=94;
uint8 EMACRecieveFlag;
uint8 *Rx_packet_address;
void emacRecieve(hdkif_t *hdkif);
void create_packet()
{
int i,j;
for(i=0;i<5;i++)
{
pack[i].tot_len = size1;
pack[i].len = size2;
for(j=0;j<6;j++)
{
data[i][j] = 0xffu;
}
for(j=0;j<6;j++)
{
data[i][j+6]= emacAddress[j];
}
data[i][12] = 0;
data[i][13] = 80;
for(j=0;j<80;j++)
{
data[i][j+14] = i+5;
}
pack[i].payload = &data[i][0];
if(i!=4)
pack[i].next = &pack[i+1];
}
pack[4].next= NULL;
}
/* USER CODE END */
int main(void)
{
/* USER CODE BEGIN (3) */
int i=0,j=0;
EMACRecieveFlag=0;
_enable_IRQ();
EMACHWInit(emacAddress);
HWREG(0xFCF78160) = 0x00008029; // RXBUFFFLOW ENABLE
HWREG(0xFCF7816C) = 0x00000002;
HWREG(0xFCF78508) = 0x00000001;
HWREG(0xFCF78100) = 0x01E12121;
MDIOPhyRegWrite(0xFCF78900, 0x00000001, 0x00, 0x6100);
/* for(i=0;i<5000;i++)
{
for(j=0;j<10000;j++);
}*/
MDIOPhyRegWrite(0xFCF78900, 0x00000001, 0x17, 0x0020);
MDIOPhyRegWrite(0xFCF78900, 0x00000001, 0x17, 0x0021);
/* for(i=0;i<5000;i++)
{
for(j=0;j<10000;j++);
}*/
MDIOPhyRegWrite(0xFCF78900, 0x00000001, 0x17, 0x0020);
/* for(i=0;i<5000;i++)
{
for(j=0;j<10000;j++);
}*/
MDIOPhyRegRead(0xFCF78900, 0x00000001, 0x10, 0x00);
MDIOPhyRegRead(0xFCF78900, 0x00000001, 0x17, 0x00);
/*for(i=0;i<5000;i++)
{
for(j=0;j<10000;j++);
}*/
MDIOPhyRegRead(0xFCF78900, 0x00000001, 0x00, 0x00);
/*for(i=0;i<5000;i++)
{
for(j=0;j<10000;j++);
}*/
create_packet();
/*EMACTransmit(&hdkif_data[0], &pack[0]);
size1=600;
size2=120;
create_packet();*/
while(1)
{
EMACTransmit(&hdkif_data[0], &pack[0]);
// emacRecieve(&hdkif_data[0]);
EMACReceive(&hdkif_data[0]);
}
/* USER CODE END */
}
/* USER CODE BEGIN (4) */
/* USER CODE END */
/**
* \file emac.c
*
* \brief EMAC APIs.
*
* This file contains the device abstraction layer APIs for EMAC.
*/
/*
* Copyright (C) 2009-2018 Texas Instruments Incorporated - www.ti.com
*
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 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.
*
* Neither the name of Texas Instruments Incorporated nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "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 COPYRIGHT
* OWNER OR CONTRIBUTORS 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.
*
*/
/* USER CODE BEGIN (0) */
/* USER CODE END */
#include "emac.h"
#include "sys_vim.h"
/* USER CODE BEGIN (1) */
/* USER CODE END */
/* Defining interface for all the emac instances */
hdkif_t hdkif_data[MAX_EMAC_INSTANCE];
/*SAFETYMCUSW 25 D MR:8.7 <APPROVED> "Statically allocated memory needs to be available to entire application." */
static uint8_t pbuf_array[MAX_RX_PBUF_ALLOC][MAX_TRANSFER_UNIT];
/*******************************************************************************
* INTERNAL MACRO DEFINITIONS
*******************************************************************************/
#define EMAC_CONTROL_RESET (0x01U)
#define EMAC_SOFT_RESET (0x01U)
#define EMAC_MAX_HEADER_DESC (8U)
#define EMAC_UNICAST_DISABLE (0xFFU)
/*******************************************************************************
* API FUNCTION DEFINITIONS
*******************************************************************************/
/**
* \brief Enables the TXPULSE Interrupt Generation.
*
* \param emacBase Base address of the EMAC Module registers.
* \param emacCtrlBase Base address of the EMAC CONTROL module registers
* \param ctrlCore Channel number for which the interrupt to be enabled in EMAC Control module
* \param channel Channel number for which interrupt to be enabled
*
* \return None
*
**/
/* SourceId : ETH_SourceId_001 */
/* DesignId : ETH_DesignId_001*/
/* Requirements : HL_ETH_SR15 */
void EMACTxIntPulseEnable(uint32 emacBase, uint32 emacCtrlBase, uint32 ctrlCore, uint32 channel)
{
HWREG(emacBase + EMAC_TXINTMASKSET) |= ((uint32)1U << channel);
HWREG(emacCtrlBase + EMAC_CTRL_CnTXEN(ctrlCore)) |= ((uint32)1U << channel);
}
/**
* \brief Disables the TXPULSE Interrupt Generation.
*
* \param emacBase Base address of the EMAC Module registers.
* \param emacCtrlBase Base address of the EMAC CONTROL module registers
* \param ctrlCore Channel number for which the interrupt to be enabled in EMAC Control module
* \param channel Channel number for which interrupt to be disabled
*
* \return None
*
**/
/* SourceId : ETH_SourceId_002 */
/* DesignId : ETH_DesignId_002*/
/* Requirements : HL_ETH_SR15 */
void EMACTxIntPulseDisable(uint32 emacBase, uint32 emacCtrlBase, uint32 ctrlCore, uint32 channel)
/*SAFETYMCUSW 1 J MR:14.1 <APPROVED> "LDRA Tool issue." */
{
HWREG(emacBase + EMAC_TXINTMASKCLEAR) |= ((uint32)1U << channel);
HWREG(emacCtrlBase + EMAC_CTRL_CnTXEN(ctrlCore)) &= (~((uint32)1U << channel));
}
/**
* \brief Enables the RXPULSE Interrupt Generation.
*
* \param emacBase Base address of the EMAC Module registers.
* \param emacCtrlBase Base address of the EMAC CONTROL module registers
* \param ctrlCore Control core for which the interrupt to be enabled.
* \param channel Channel number for which interrupt to be enabled
*
* \return None
*
**/
/* SourceId : ETH_SourceId_003 */
/* DesignId : ETH_DesignId_003*/
/* Requirements : HL_ETH_SR15 */
void EMACRxIntPulseEnable(uint32 emacBase, uint32 emacCtrlBase, uint32 ctrlCore, uint32 channel)
/*SAFETYMCUSW 1 J MR:14.1 <APPROVED> "LDRA Tool issue." */
{
HWREG(emacBase + EMAC_RXINTMASKSET) |= ((uint32)1U << channel);
HWREG(emacCtrlBase + EMAC_CTRL_CnRXEN(ctrlCore)) |= ((uint32)1U << channel);
}
/**
* \brief Disables the RXPULSE Interrupt Generation.
*
* \param emacBase Base address of the EMAC Module registers.
* \param emacCtrlBase Base address of the EMAC CONTROL module registers
* \param ctrlCore Control core for which the interrupt to be disabled.
* \param channel Channel number for which interrupt to be disabled
*
* \return None
*
**/
/* SourceId : ETH_SourceId_004 */
/* DesignId : ETH_DesignId_004*/
/* Requirements : HL_ETH_SR15 */
void EMACRxIntPulseDisable(uint32 emacBase, uint32 emacCtrlBase, uint32 ctrlCore, uint32 channel)
{
HWREG(emacBase + EMAC_RXINTMASKCLEAR) |= ((uint32)1U << channel);
HWREG(emacCtrlBase + EMAC_CTRL_CnRXEN(ctrlCore)) &= (~((uint32)1U << channel));
}
/**
* \brief This API sets the RMII speed. The RMII Speed can be 10 Mbps or
* 100 Mbps
*
* \param emacBase Base address of the EMAC Module registers.
* \param speed speed for setting.
* speed can take the following values. \n
* EMAC_RMIISPEED_10MBPS - 10 Mbps \n
* EMAC_RMIISPEED_100MBPS - 100 Mbps.
*
* \return None
*
**/
/* SourceId : ETH_SourceId_005 */
/* DesignId : ETH_DesignId_005*/
/* Requirements : HL_ETH_SR19 */
void EMACRMIISpeedSet(uint32 emacBase, uint32 speed)
{
HWREG(emacBase + EMAC_MACCONTROL) &= (~(uint32)EMAC_MACCONTROL_RMIISPEED);
HWREG(emacBase + EMAC_MACCONTROL) |= speed;
}
/* SourceId : ETH_SourceId_006 */
/* DesignId : ETH_DesignId_006*/
/* Requirements : HL_ETH_SR18 */
/**
* \brief This API set the GMII bit, RX and TX are enabled for receive and transmit.
* Note: This is not the API to enable MII.
* \param emacBase Base address of the EMAC Module registers.
*
* \return None
*
**/
void EMACMIIEnable(uint32 emacBase)
{
HWREG(emacBase + EMAC_MACCONTROL) |= EMAC_MACCONTROL_GMIIEN;
}
/**
* \brief This API clears the GMII bit, Rx and Tx are held in reset.
* Note: This is not the API to disable MII.
* \param emacBase Base address of the EMAC Module registers.
*
* \return None
*
**/
/* SourceId : ETH_SourceId_007 */
/* DesignId : ETH_DesignId_007*/
/* Requirements : HL_ETH_SR18 */
void EMACMIIDisable(uint32 emacBase)
/*SAFETYMCUSW 1 J MR:14.1 <APPROVED> "LDRA Tool issue." */
{
HWREG(emacBase + EMAC_MACCONTROL) &= (~(uint32)EMAC_MACCONTROL_GMIIEN);
}
/**
* \brief This API sets the duplex mode of operation(full/half) for MAC.
*
* \param emacBase Base address of the EMAC Module registers.
* \param duplexMode duplex mode of operation.
* duplexMode can take the following values. \n
* EMAC_DUPLEX_FULL - Full Duplex \n
* EMAC_DUPLEX_HALF - Half Duplex.
*
* \return None
*
**/
/* SourceId : ETH_SourceId_008 */
/* DesignId : ETH_DesignId_008*/
/* Requirements : HL_ETH_SR21 */
void EMACDuplexSet(uint32 emacBase, uint32 duplexMode)
{
HWREG(emacBase + EMAC_MACCONTROL) &= (~(uint32)EMAC_MACCONTROL_FULLDUPLEX);
HWREG(emacBase + EMAC_MACCONTROL) |= duplexMode;
}
/**
* \brief API to enable the transmit in the TX Control Register
* After the transmit is enabled, any write to TXHDP of
* a channel will start transmission
*
* \param emacBase Base Address of the EMAC Module Registers.
*
* \return None
*
**/
/* SourceId : ETH_SourceId_009 */
/* DesignId : ETH_DesignId_009*/
/* Requirements : HL_ETH_SR21 */
void EMACTxEnable(uint32 emacBase)
{
HWREG(emacBase + EMAC_TXCONTROL) = EMAC_TXCONTROL_TXEN;
}
/**
* \brief API to disable the transmit in the TX Control Register
*
* \param emacBase Base Address of the EMAC Module Registers.
*
* \return None
*
**/
/* SourceId : ETH_SourceId_010 */
/* DesignId : ETH_DesignId_010*/
/* Requirements : HL_ETH_SR21 */
void EMACTxDisable(uint32 emacBase)
/*SAFETYMCUSW 1 J MR:14.1 <APPROVED> "LDRA Tool issue." */
{
HWREG(emacBase + EMAC_TXCONTROL) = EMAC_TXCONTROL_TXDIS;
}
/**
* \brief API to enable the receive in the RX Control Register
* After the receive is enabled, and write to RXHDP of
* a channel, the data can be received in the destination
* specified by the corresponding RX buffer descriptor.
*
* \param emacBase Base Address of the EMAC Module Registers.
*
* \return None
*
**/
/* SourceId : ETH_SourceId_011*/
/* DesignId : ETH_DesignId_011*/
/* Requirements : HL_ETH_SR21 */
void EMACRxEnable(uint32 emacBase)
{
HWREG(emacBase + EMAC_RXCONTROL) = EMAC_RXCONTROL_RXEN;
}
/**
* \brief API to disable the receive in the RX Control Register
*
* \param emacBase Base Address of the EMAC Module Registers.
*
* \return None
*
**/
/* SourceId : ETH_SourceId_012*/
/* DesignId : ETH_DesignId_012*/
/* Requirements : HL_ETH_SR21 */
void EMACRxDisable(uint32 emacBase)
/*SAFETYMCUSW 1 J MR:14.1 <APPROVED> "LDRA Tool issue." */
{
HWREG(emacBase + EMAC_RXCONTROL) = EMAC_RXCONTROL_RXDIS;
}
/**
* \brief API to write the TX HDP register. If transmit is enabled,
* write to the TX HDP will immediately start transmission.
* The data will be taken from the buffer pointer of the TX buffer
* descriptor written to the TX HDP
*
* \param emacBase Base Address of the EMAC Module Registers.\n
* \param descHdr Address of the TX buffer descriptor
* \param channel Channel Number
*
* \return None
*
**/
/* SourceId : ETH_SourceId_013*/
/* DesignId : ETH_DesignId_013*/
/* Requirements : HL_ETH_SR16 */
void EMACTxHdrDescPtrWrite(uint32 emacBase, uint32 descHdr,
uint32 channel)
{
HWREG(emacBase + EMAC_TXHDP(channel)) = descHdr;
}
/**
* \brief API to write the RX HDP register. If receive is enabled,
* write to the RX HDP will enable data reception to point to
* the corresponding RX buffer descriptor's buffer pointer.
*
* \param emacBase Base Address of the EMAC Module Registers.\n
* \param descHdr Address of the RX buffer descriptor
* \param channel Channel Number
*
* \return None
*
**/
/* SourceId : ETH_SourceId_014 */
/* DesignId : ETH_DesignId_014*/
/* Requirements : HL_ETH_SR16 */
void EMACRxHdrDescPtrWrite(uint32 emacBase, uint32 descHdr, uint32 channel)
{
HWREG(emacBase + EMAC_RXHDP(channel)) = descHdr;
}
/**
* \brief This API Initializes the EMAC and EMAC Control modules. The
* EMAC Control module is reset, the CPPI RAM is cleared. also,
* all the interrupts are disabled. This API does not enable any
* interrupt or operation of the EMAC.
*
* \param emacCtrlBase Base Address of the EMAC Control module
* registers.\n
* \param emacBase Base address of the EMAC module registers
*
* \return None
*
**/
/* SourceId : ETH_SourceId_015 */
/* DesignId : ETH_DesignId_015*/
/* Requirements : HL_ETH_SR6 */
void EMACInit(uint32 emacCtrlBase, uint32 emacBase)
{
uint32 cnt;
/* Reset the EMAC Control Module. This clears the CPPI RAM also */
HWREG(emacCtrlBase + EMAC_CTRL_SOFTRESET) = EMAC_CONTROL_RESET;
/*SAFETYMCUSW 28 D MR:NA <APPROVED> "Hardware status bit read check" */
while((HWREG(emacCtrlBase + EMAC_CTRL_SOFTRESET) & EMAC_CONTROL_RESET) == EMAC_CONTROL_RESET)
{
} /* Wait */
/* Reset the EMAC Module. This clears the CPPI RAM also */
HWREG(emacBase + EMAC_SOFTRESET) = EMAC_SOFT_RESET;
/*SAFETYMCUSW 28 D MR:NA <APPROVED> "Hardware status bit read check" */
while((HWREG(emacBase + EMAC_SOFTRESET) & EMAC_SOFT_RESET) == EMAC_SOFT_RESET )
{
} /* Wait */
HWREG(emacBase + EMAC_MACCONTROL)= 0U;
HWREG(emacBase + EMAC_RXCONTROL)= 0U;
HWREG(emacBase + EMAC_TXCONTROL)= 0U;
/* Initialize all the header descriptor pointer registers */
for(cnt = 0U; cnt< EMAC_MAX_HEADER_DESC; cnt++)
{
HWREG(emacBase + EMAC_RXHDP(cnt)) = 0U;
HWREG(emacBase + EMAC_TXHDP(cnt)) = 0U;
HWREG(emacBase + EMAC_RXCP(cnt)) = 0U;
HWREG(emacBase + EMAC_TXCP(cnt)) = 0U;
HWREG(emacBase + EMAC_RXFREEBUFFER(cnt)) = 0xFFU;
}
/* Clear the interrupt enable for all the channels */
HWREG(emacBase + EMAC_TXINTMASKCLEAR) = 0xFFU;
HWREG(emacBase + EMAC_RXINTMASKCLEAR) = 0xFFU;
HWREG(emacBase + EMAC_MACHASH1) = 0U;
HWREG(emacBase + EMAC_MACHASH2) = 0U;
HWREG(emacBase + EMAC_RXBUFFEROFFSET) = 0U;
}
/**
* \brief Sets the MAC Address in MACSRCADDR registers.
*
* \param emacBase Base Address of the EMAC module registers.
* \param macAddr Start address of a MAC address array.
* The array[0] shall be the LSB of the MAC address
*
* \return None
*
**/
/* SourceId : ETH_SourceId_016 */
/* DesignId : ETH_DesignId_016*/
/* Requirements : HL_ETH_SR7 */
void EMACMACSrcAddrSet(uint32 emacBase, uint8 macAddr[6])
{
HWREG(emacBase + EMAC_MACSRCADDRHI) = ((uint32)macAddr[5U] |((uint32)macAddr[4U] << 8U)
|((uint32)macAddr[3U] << 16U) |((uint32)macAddr[2U] << 24U));
HWREG(emacBase + EMAC_MACSRCADDRLO) = ((uint32)macAddr[1U] | ((uint32)macAddr[0U] << 8U));
}
/**
* \brief Sets the MAC Address in MACADDR registers.
*
* \param emacBase Base Address of the EMAC module registers.
* \param channel Channel Number
* \param matchFilt Match or Filter
* \param macAddr Start address of a MAC address array.
* The array[0] shall be the LSB of the MAC address
* matchFilt can take the following values \n
* EMAC_MACADDR_NO_MATCH_NO_FILTER - Address is not used to match
* or filter incoming packet. \n
* EMAC_MACADDR_FILTER - Address is used to filter incoming packets \n
* EMAC_MACADDR_MATCH - Address is used to match incoming packets \n
*
* \return None
*
**/
/* SourceId : ETH_SourceId_017 */
/* DesignId : ETH_DesignId_017*/
/* Requirements : HL_ETH_SR7 */
void EMACMACAddrSet(uint32 emacBase, uint32 channel, uint8 macAddr[6], uint32 matchFilt)
{
HWREG(emacBase + EMAC_MACINDEX) = channel;
HWREG(emacBase + EMAC_MACADDRHI) = ((uint32)macAddr[5U] |((uint32)macAddr[4U] << 8U)
|((uint32)macAddr[3U] << 16U) |((uint32)macAddr[2U] << 24U));
HWREG(emacBase + EMAC_MACADDRLO) = ((uint32)macAddr[1U] | ((uint32)macAddr[0U] << 8U)
| matchFilt | (channel << 16U));
}
/**
* \brief Acknowledges an interrupt processed to the EMAC Control Core.
*
* \param emacBase Base Address of the EMAC module registers.
* \param eoiFlag Type of interrupt to acknowledge to the EMAC Control
* module.
* eoiFlag can take the following values \n
* EMAC_INT_CORE0_TX - Core 0 TX Interrupt
* EMAC_INT_CORE1_TX - Core 1 TX Interrupt
* EMAC_INT_CORE2_TX - Core 2 TX Interrupt
* EMAC_INT_CORE0_RX - Core 0 RX Interrupt
* EMAC_INT_CORE1_RX - Core 1 RX Interrupt
* EMAC_INT_CORE2_RX - Core 2 RX Interrupt
* \return None
*
**/
/* SourceId : ETH_SourceId_018 */
/* DesignId : ETH_DesignId_018*/
/* Requirements : HL_ETH_SR15 */
void EMACCoreIntAck(uint32 emacBase, uint32 eoiFlag)
{
/* Acknowledge the EMAC Control Core */
HWREG(emacBase + EMAC_MACEOIVECTOR) = eoiFlag;
}
/**
* \brief Writes the the TX Completion Pointer for a specific channel
*
* \param emacBase Base Address of the EMAC module registers.
* \param channel Channel Number.
* \param comPtr Completion Pointer Value to be written
*
* \return None
*
**/
/* SourceId : ETH_SourceId_019 */
/* DesignId : ETH_DesignId_019*/
/* Requirements : HL_ETH_SR27 */
void EMACTxCPWrite(uint32 emacBase, uint32 channel, uint32 comPtr)
{
HWREG(emacBase + EMAC_TXCP(channel)) = comPtr;
}
/**
* \brief Writes the the RX Completion Pointer for a specific channel
*
* \param emacBase Base Address of the EMAC module registers.
* \param channel Channel Number.
* \param comPtr Completion Pointer Value to be written
*
* \return None
*
**/
/* SourceId : ETH_SourceId_020 */
/* DesignId : ETH_DesignId_020*/
/* Requirements : HL_ETH_SR27 */
void EMACRxCPWrite(uint32 emacBase, uint32 channel, uint32 comPtr)
{
HWREG(emacBase + EMAC_RXCP(channel)) = comPtr;
}
/**
* \brief Enables a specific channel to receive broadcast frames
*
* \param emacBase Base Address of the EMAC module registers.
* \param channel Channel Number.
*
* \return None
*
**/
/* SourceId : ETH_SourceId_021 */
/* DesignId : ETH_DesignId_021*/
/* Requirements : HL_ETH_SR28 */
void EMACRxBroadCastEnable(uint32 emacBase, uint32 channel)
{
HWREG(emacBase + EMAC_RXMBPENABLE) &= (~(uint32)EMAC_RXMBPENABLE_RXBROADCH);
HWREG(emacBase + EMAC_RXMBPENABLE) |= ((uint32)EMAC_RXMBPENABLE_RXBROADEN | ((uint32)channel << (uint32)EMAC_RXMBPENABLE_RXBROADCH_SHIFT));
}
/**
* \brief Disables a specific channel to receive broadcast frames
*
* \param emacBase Base Address of the EMAC module registers.
* \param channel Channel Number.
*
* \return None
*
**/
/* SourceId : ETH_SourceId_022 */
/* DesignId : ETH_DesignId_022*/
/* Requirements : HL_ETH_SR28 */
void EMACRxBroadCastDisable(uint32 emacBase, uint32 channel)
/*SAFETYMCUSW 1 J MR:14.1 <APPROVED> "LDRA Tool issue." */
{
HWREG(emacBase + EMAC_RXMBPENABLE) &= (~(uint32)EMAC_RXMBPENABLE_RXBROADCH);
/* Broadcast Frames are filtered. */
HWREG(emacBase + EMAC_RXMBPENABLE) &= (~(uint32)EMAC_RXMBPENABLE_RXBROADEN);
}
/**
* \brief Enables a specific channel to receive multicast frames
*
* \param emacBase Base Address of the EMAC module registers.
* \param channel Channel Number.
*
* \return None
*
**/
/* SourceId : ETH_SourceId_023 */
/* DesignId : ETH_DesignId_023*/
/* Requirements : HL_ETH_SR28 */
void EMACRxMultiCastEnable(uint32 emacBase, uint32 channel)
{
HWREG(emacBase + EMAC_RXMBPENABLE) &= (~(uint32)EMAC_RXMBPENABLE_RXMULTCH);
HWREG(emacBase + EMAC_RXMBPENABLE) |= ((uint32)EMAC_RXMBPENABLE_RXMULTEN |(channel));
}
/**
* \brief Disables a specific channel to receive multicast frames
*
* \param emacBase Base Address of the EMAC module registers.
* \param channel Channel Number.
*
* \return None
*
**/
/* SourceId : ETH_SourceId_024 */
/* DesignId : ETH_DesignId_024*/
/* Requirements : HL_ETH_SR28 */
void EMACRxMultiCastDisable(uint32 emacBase, uint32 channel)
{
HWREG(emacBase + EMAC_RXMBPENABLE) &= (~(uint32)EMAC_RXMBPENABLE_RXMULTCH);
HWREG(emacBase + EMAC_RXMBPENABLE) &= (~(uint32)EMAC_RXMBPENABLE_RXMULTEN);
}
/**
* \brief Enables unicast for a specific channel
*
* \param emacBase Base Address of the EMAC module registers.
* \param channel Channel Number.
*
* \return None
*
**/
/* SourceId : ETH_SourceId_025 */
/* DesignId : ETH_DesignId_025*/
/* Requirements : HL_ETH_SR14 */
void EMACRxUnicastSet(uint32 emacBase, uint32 channel)
{
HWREG(emacBase + EMAC_RXUNICASTSET) |= ((uint32)1U << channel);
}
/**
* \brief Disables unicast for a specific channel
*
* \param emacBase Base Address of the EMAC module registers.
* \param channel Channel Number.
*
* \return None
*
**/
/* SourceId : ETH_SourceId_026 */
/* DesignId : ETH_DesignId_026*/
/* Requirements : HL_ETH_SR14 */
void EMACRxUnicastClear(uint32 emacBase, uint32 channel)
/*SAFETYMCUSW 1 J MR:14.1 <APPROVED> "LDRA Tool issue." */
{
HWREG(emacBase + EMAC_RXUNICASTCLEAR) |= ((uint32)1U << channel);
}
/**
* \brief Set the free buffers for a specific channel
*
* \param emacBase Base Address of the EMAC module registers.
* \param channel Channel Number.
* \param nBuf Number of free buffers
*
* \return None
*
**/
/* SourceId : ETH_SourceId_027 */
/* DesignId : ETH_DesignId_027*/
/* Requirements : HL_ETH_SR20 */
void EMACNumFreeBufSet(uint32 emacBase, uint32 channel,
uint32 nBuf)
{
HWREG(emacBase + EMAC_RXFREEBUFFER(channel)) = nBuf;
}
/**
* \brief Gets the interrupt vectors of EMAC, which are pending
*
* \param emacBase Base Address of the EMAC module registers.
*
* \return Vectors
*
**/
/* SourceId : ETH_SourceId_028 */
/* DesignId : ETH_DesignId_028*/
/* Requirements : HL_ETH_SR15 */
uint32 EMACIntVectorGet(uint32 emacBase)
{
return (HWREG(emacBase + EMAC_MACINVECTOR));
}
/**
* Function to setup the instance parameters inside the interface
* @param hdkif Network interface structure
* @return none.
*/
/* SourceId : ETH_SourceId_029 */
/* DesignId : ETH_DesignId_029*/
/* Requirements : HL_ETH_SR6 */
void EMACInstConfig(hdkif_t *hdkif)
{
hdkif->emac_base = EMAC_0_BASE;
hdkif->emac_ctrl_base = EMAC_CTRL_0_BASE;
hdkif->emac_ctrl_ram = EMAC_CTRL_RAM_0_BASE;
hdkif->mdio_base = MDIO_BASE;
hdkif->phy_addr = 1U;
/* (MISRA-C:2004 10.1/R) MISRA error reported with Code Composer Studio MISRA checker. */
hdkif->phy_autoneg = &Dp83640AutoNegotiate;
hdkif->phy_partnerability = &Dp83640PartnerAbilityGet;
}
/**
* Function to setup the link. AutoNegotiates with the phy for link
* setup and set the EMAC with the result of autonegotiation.
* @param hdkif Network interface structure.
* @return ERR_OK if everything passed
* others if not passed
*/
/* SourceId : ETH_SourceId_030 */
/* DesignId : ETH_DesignId_030*/
/* Requirements : HL_ETH_SR6 */
uint32 EMACLinkSetup(hdkif_t *hdkif) {
uint32 linkstat = EMAC_ERR_CONNECT;
uint16 partnr_ablty = 0U;
uint32 phyduplex = EMAC_DUPLEX_HALF;
volatile uint32 delay = 0xFFFFFU;
if(Dp83640AutoNegotiate((uint32)hdkif->mdio_base, (uint32)hdkif->phy_addr,
(uint16)((uint16)DP83640_100BTX | (uint16)DP83640_100BTX_FD
| (uint16)DP83640_10BT | (uint16)DP83640_10BT_FD)) == TRUE) {
linkstat = EMAC_ERR_OK;
/* (MISRA-C:2004 10.1/R) MISRA error reported with Code Composer Studio MISRA checker (due to use of & ?) */
(void)Dp83640PartnerAbilityGet(hdkif->mdio_base, hdkif->phy_addr,
&partnr_ablty);
/* Check for 100 Mbps and duplex capability */
if((partnr_ablty & DP83640_100BTX_FD) != 0U) {
phyduplex = EMAC_DUPLEX_FULL;
}
}
else {
linkstat = EMAC_ERR_CONNECT;
}
/* Set the EMAC with the negotiation results if it is successful */
if(linkstat == EMAC_ERR_OK) {
EMACDuplexSet(hdkif->emac_base, phyduplex);
}
/* Wait for the MII to settle down */
/*SAFETYMCUSW 134 S MR:12.2 <APPROVED> "LDRA Tool issue" */
while(delay != 0U)
{
delay--;
}
return linkstat;
}
/**
* \brief Perform a transmit queue teardown, that is, transmission is aborted.
*
* \param emacBase Base Address of the EMAC module registers.
* \param channel Channel Number.
*
* \return None
*
**/
/* SourceId : ETH_SourceId_031 */
/* DesignId : ETH_DesignId_031*/
/* Requirements : HL_ETH_SR22 */
void EMACTxTeardown(uint32 emacBase, uint32 channel)
{
HWREG(emacBase + EMAC_TXTEARDOWN) &= (channel);
}
/**
* \brief Perform a receive queue teardown, that is, reception is aborted.
*
* \param emacBase Base Address of the EMAC module registers.
* \param channel Channel Number.
*
* \return None
*
**/
/* SourceId : ETH_SourceId_032 */
/* DesignId : ETH_DesignId_032*/
/* Requirements : HL_ETH_SR22 */
void EMACRxTeardown(uint32 emacBase, uint32 channel)
{
HWREG(emacBase + EMAC_RXTEARDOWN) &= (channel);
}
/**
* \brief Perform multicast frame filtering using the MAC Hash Registers.
*
* \param emacBase Base Address of the EMAC module registers.
* \param hashTable The hash table which specifies which bits are to be accepted.
*
* \return None
*
**/
/* SourceId : ETH_SourceId_033 */
/* DesignId : ETH_DesignId_033*/
/* Requirements : HL_ETH_SR24 */
void EMACFrameSelect(uint32 emacBase, uint64 hashTable)
{
HWREG(emacBase + EMAC_MACHASH1) = (uint32)(hashTable & 0xFFFFFFFFU);
HWREG(emacBase + EMAC_MACHASH2) = (uint32)(hashTable >> 32U);
}
/**
* \brief Sets the Transmit Queue Priority type in the MACCONTROL Register
*
* \param emacBase Base Address of the EMAC module registers.
* \param txPType The Transmit Queue Priority Type.
* 0 results in a round-robin scheme being used to select the next channel, while 1 results
* in a fixed-priority scheme( channel 7 highest priority).
*
* \return None
*
**/
/* SourceId : ETH_SourceId_034 */
/* DesignId : ETH_DesignId_034*/
/* Requirements : HL_ETH_SR25 */
void EMACTxPrioritySelect(uint32 emacBase, uint32 txPType)
{
/* 1- The queue uses a fixed-priority (channel 7 highest priority) scheme */
if(txPType == 1U)
{
HWREG(emacBase + EMAC_MACCONTROL) &= (~(uint32)(EMAC_MACCONTROL_TXPTYPE));
HWREG(emacBase + EMAC_MACCONTROL) |= EMAC_MACCONTROL_TXPTYPE;
}
else
{
HWREG(emacBase + EMAC_MACCONTROL) &= (~(uint32)(EMAC_MACCONTROL_TXPTYPE));
}
}
/**
* \brief Performs a soft reset of the EMAC and EMAC Control Modules.
*
* \param emacCtrlBase Base address of the EMAC CONTROL module registers
* \param emacBase Base Address of the EMAC module registers.
* \return None
*
**/
/* SourceId : ETH_SourceId_035 */
/* DesignId : ETH_DesignId_035*/
/* Requirements : HL_ETH_SR26 */
void EMACSoftReset(uint32 emacCtrlBase, uint32 emacBase)
{
/* Reset the EMAC Control Module. This clears the CPPI RAM also */
HWREG(emacCtrlBase + EMAC_CTRL_SOFTRESET) = EMAC_CONTROL_RESET;
/*SAFETYMCUSW 28 D MR:NA <APPROVED> "Hardware status bit read check" */
while((HWREG(emacCtrlBase + EMAC_CTRL_SOFTRESET) & EMAC_CONTROL_RESET) == EMAC_CONTROL_RESET)
{
/* Wait for the reset to complete */
}
/* Reset the EMAC Module. */
HWREG(emacBase + EMAC_SOFTRESET) = EMAC_SOFT_RESET;
/*SAFETYMCUSW 28 D MR:NA <APPROVED> "Hardware status bit read check" */
while((HWREG(emacBase + EMAC_SOFTRESET) & EMAC_SOFT_RESET) == EMAC_SOFT_RESET )
{
/* Wait for the Reset to complete */
}
}
/**
* \brief Enable Idle State of the EMAC Module.
*
* \param emacBase Base Address of the EMAC module registers.
* \return None
*
**/
/* SourceId : ETH_SourceId_036 */
/* DesignId : ETH_DesignId_036*/
/* Requirements : HL_ETH_SR32 */
void EMACEnableIdleState(uint32 emacBase)
{
HWREG(emacBase + EMAC_MACCONTROL) |= EMAC_MACCONTROL_CMDIDLE;
}
/**
* \brief Disable Idle State of the EMAC Module.
*
* \param emacBase Base Address of the EMAC module registers.
* \return None
*
**/
/* SourceId : ETH_SourceId_037 */
/* DesignId : ETH_DesignId_037*/
/* Requirements : HL_ETH_SR32 */
void EMACDisableIdleState(uint32 emacBase)
{
HWREG(emacBase + EMAC_MACCONTROL) &= (~(uint32)(EMAC_MACCONTROL_CMDIDLE));
}
/**
* \brief Enables Loopback Mode.
*
* \param emacBase Base Address of the EMAC module registers.
* \return None
*
**/
/* SourceId : ETH_SourceId_038 */
/* DesignId : ETH_DesignId_038*/
/* Requirements : HL_ETH_SR50 */
void EMACEnableLoopback(uint32 emacBase)
/*SAFETYMCUSW 1 J MR:14.1 <APPROVED> "LDRA Tool issue." */
{
uint32 GMIIENval=0U;
/*Store the value of GMIIEN bit before deasserting it */
GMIIENval = HWREG(emacBase + EMAC_MACCONTROL) & EMAC_MACCONTROL_GMIIEN;
HWREG(emacBase + EMAC_MACCONTROL) &= (~(uint32)EMAC_MACCONTROL_GMIIEN);
/*Enable Loopback */
HWREG(emacBase + EMAC_MACCONTROL) |= EMAC_MACCONTROL_LOOPBACK;
/*Restore the value of GMIIEN bit */
HWREG(emacBase + EMAC_MACCONTROL) |= GMIIENval;
}
/**
* \brief Disables Loopback Mode.
*
* \param emacBase Base Address of the EMAC module registers.
* \return None
*
**/
/* SourceId : ETH_SourceId_039 */
/* DesignId : ETH_DesignId_039*/
/* Requirements : HL_ETH_SR50 */
void EMACDisableLoopback(uint32 emacBase)
{
uint32 GMIIENval=0U;
/*Store the value of GMIIEN bit before deasserting it */
GMIIENval = HWREG(emacBase + EMAC_MACCONTROL) & EMAC_MACCONTROL_GMIIEN;
HWREG(emacBase + EMAC_MACCONTROL) &= (~(uint32)EMAC_MACCONTROL_GMIIEN);
/*Disable Loopback */
HWREG(emacBase + EMAC_MACCONTROL) &= (~(uint32)EMAC_MACCONTROL_LOOPBACK);
/*Restore the value of GMIIEN bit */
HWREG(emacBase + EMAC_MACCONTROL) |= GMIIENval;
}
/**
* \brief Enable Transmit Flow Control.
*
* \param emacBase Base Address of the EMAC module registers.
* \return None
*
**/
/* SourceId : ETH_SourceId_040 */
/* DesignId : ETH_DesignId_040*/
/* Requirements : HL_ETH_SR20 */
void EMACTxFlowControlEnable(uint32 emacBase)
{
HWREG(emacBase + EMAC_MACCONTROL) |= EMAC_MACCONTROL_TXFLOWEN;
}
/**
* \brief Disable Transmit Flow Control.
*
* \param emacBase Base Address of the EMAC module registers.
* \return None
*
**/
/* SourceId : ETH_SourceId_041 */
/* DesignId : ETH_DesignId_041*/
/* Requirements : HL_ETH_SR20 */
void EMACTxFlowControlDisable(uint32 emacBase)
{
HWREG(emacBase + EMAC_MACCONTROL) &= (~(uint32)EMAC_MACCONTROL_TXFLOWEN);
}
/**
* \brief Enable Receive Flow Control.
*
* \param emacBase Base Address of the EMAC module registers.
* \return None
*
**/
/* SourceId : ETH_SourceId_042 */
/* DesignId : ETH_DesignId_042*/
/* Requirements : HL_ETH_SR20 */
void EMACRxFlowControlEnable(uint32 emacBase)
{
HWREG(emacBase + EMAC_MACCONTROL) |= EMAC_MACCONTROL_RXBUFFERFLOWEN;
}
/**
* \brief Disable Receive Flow Control.
*
* \param emacBase Base Address of the EMAC module registers.
* \return None
*
**/
/* SourceId : ETH_SourceId_043 */
/* DesignId : ETH_DesignId_043*/
/* Requirements : HL_ETH_SR20 */
void EMACRxFlowControlDisable(uint32 emacBase)
{
HWREG(emacBase + EMAC_MACCONTROL) &= (~(uint32)EMAC_MACCONTROL_RXBUFFERFLOWEN);
}
/**
* \brief Receive flow threshold. These bits contain the threshold value for issuing flow control on incoming frames for channel n (when enabled).
*
* \param emacBase Base Address of the EMAC module registers.
* \param channel Channel Number
* \param threshold threshold value for issuing flow control on incoming frames for the given channel
* \return None
*
**/
/* SourceId : ETH_SourceId_044 */
/* DesignId : ETH_DesignId_044*/
/* Requirements : HL_ETH_SR20 */
void EMACRxSetFlowThreshold(uint32 emacBase, uint32 channel, uint32 threshold)
{
HWREG(emacBase + EMAC_RXFLOWTHRESH(channel)) &= (0x0U);
HWREG(emacBase + EMAC_RXFLOWTHRESH(channel)) |= threshold;
}
/**
* \brief This function reads the contents of the 36 network statistics registers that are present in the module.
* \param emacBase Base Address of the EMAC module registers.
* \param statRegNo The number of the register with RXGOODFRAMES (Offset= 0x200) being 0. Refer the Technical Reference Manual for the list of registers and their contents.
* \return uint32
**/
/* SourceId : ETH_SourceId_045 */
/* DesignId : ETH_DesignId_045*/
/* Requirements : HL_ETH_SR29 */
uint32 EMACReadNetStatRegisters(uint32 emacBase, uint32 statRegNo)
{
return HWREG(emacBase + EMAC_NETSTATREGS(statRegNo));
}
/**
* \brief Function to read values of Transmit Interrupt Status registers (TXINTSTATMASKED and TXINTSTATRAW)
*
* \param emacBase Base Address of the EMAC module registers.
* \param channel Channel Number
* \param txintstat pointer to the emac_tx_int_status Structure that will store the register values that have been read
* \return None
*
**/
/* SourceId : ETH_SourceId_046 */
/* DesignId : ETH_DesignId_046*/
/* Requirements : HL_ETH_SR23 */
void EMACTxIntStat(uint32 emacBase, uint32 channel, emac_tx_int_status_t *txintstat)
{
txintstat->intstatmasked = (HWREG(emacBase + EMAC_TXINTSTATMASKED) & ((uint32)1U << channel));
txintstat->intstatraw = (HWREG(emacBase + EMAC_TXINTSTATRAW) & ((uint32)1U << channel));
}
/**
* \brief Function to read values of Receive Interrupt Status registers (RXINTSTATMASKED, RXINTSTATRAW)
*
* \param emacBase Base Address of the EMAC module registers.
* \param channel Channel Number
* \param rxintstat pointer to the emac_rx_int_status Structure that will store the register values that have been read.
* \return None
**/
/* SourceId : ETH_SourceId_047 */
/* DesignId : ETH_DesignId_047*/
/* Requirements : HL_ETH_SR23 */
void EMACRxIntStat(uint32 emacBase, uint32 channel, emac_rx_int_status_t *rxintstat)
{
rxintstat->intstatmasked_pend = (HWREG(emacBase + EMAC_RXINTSTATMASKED) & ((uint32)0x1U << (uint32)(channel)));
rxintstat->intstatmasked_threshpend = (HWREG(emacBase + EMAC_RXINTSTATMASKED) & ((uint32)0x1U << ((uint32)0x8U + (uint32)(channel))));
rxintstat->intstatraw_pend = (HWREG(emacBase + EMAC_RXINTSTATRAW) & ((uint32)0x1U << (uint32)(channel)));
rxintstat->intstatraw_threshpend = (HWREG(emacBase + EMAC_RXINTSTATRAW) & ((uint32)0x1U << ((uint32)0x8U + (uint32)(channel))));
}
/**
* \brief Tx and Rx Buffer Descriptors are initialized. Buffer pointers are allocated to the Rx Descriptors.
*
* \param hdkif network interface structure
* \return None
*
**/
/* SourceId : ETH_SourceId_048 */
/* DesignId : ETH_DesignId_048*/
/* Requirements : HL_ETH_SR17,HL_ETH_SR30 */
void EMACDMAInit(hdkif_t *hdkif)
{
uint32 num_bd, pbuf_cnt = 0U;
volatile emac_tx_bd_t *curr_txbd, *last_txbd;
volatile emac_rx_bd_t *curr_bd, *last_bd;
txch_t *txch_dma;
rxch_t *rxch_dma;
uint8_t *p;
txch_dma = &(hdkif->txchptr);
/**
* Initialize the Descriptor Memory For TX and RX
* Only single channel is supported for both TX and RX
*/
/*SAFETYMCUSW 134 S MR:12.2 <APPROVED> "LDRA Tool issue" */
/*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are assigned in this driver" */
txch_dma->free_head = (volatile emac_tx_bd_t*)(hdkif->emac_ctrl_ram);
txch_dma->next_bd_to_process = txch_dma->free_head;
txch_dma->active_tail = NULL;
/* Set the number of descriptors for the channel */
num_bd = (SIZE_EMAC_CTRL_RAM >> 1U) / sizeof(emac_tx_bd_t);
/*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are assigned in this driver" */
curr_txbd = txch_dma->free_head;
/*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are assigned in this driver" */
last_txbd = curr_txbd;
/* Initialize all the TX buffer Descriptors */
while(num_bd != 0U) {
/*SAFETYMCUSW 567 S MR:17.1,17.4 <APPROVED> "Struct pointer used for linked list is incremented." */
curr_txbd->next = curr_txbd + 1U;
/*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are assigned in this driver" */
curr_txbd->flags_pktlen = 0U;
/*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are assigned in this driver" */
last_txbd = curr_txbd;
/*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are assigned in this driver" */
curr_txbd = curr_txbd->next;
num_bd--;
}
/*SAFETYMCUSW 134 S MR:12.2 <APPROVED> "LDRA Tool issue" */
/*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are assigned in this driver" */
last_txbd->next = txch_dma->free_head;
/* Initialize the descriptors for the RX channel */
/*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are assigned in this driver" */
rxch_dma = &(hdkif->rxchptr);
/*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are assigned in this driver" */
/*SAFETYMCUSW 567 S MR:17.1,17.4 <APPROVED> "Struct pointer used for linked list is incremented." */
curr_txbd++;
/*SAFETYMCUSW 94 S MR:11.1,11.2,11.4 <APPROVED> "Linked List pointer needs to be assigned." */
/*SAFETYMCUSW 95 S MR:11.1,11.4 <APPROVED> "Linked List pointer needs to be assigned." */
/*SAFETYMCUSW 344 S MR:11.5 <APPROVED> "Linked List pointer needs to be assigned to a different structure." */
/*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are assigned in this driver" */
rxch_dma->active_head = (volatile emac_rx_bd_t *)curr_txbd;
/*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are assigned in this driver" */
rxch_dma->free_head = NULL;
/*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are assigned in this driver" */
curr_bd = rxch_dma->active_head;
/*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are assigned in this driver" */
last_bd = curr_bd;
/*
** Static allocation of a specific number of packet buffers as specified by MAX_RX_PBUF_ALLOC, whose value is entered by the user in HALCoGen GUI.
*/
/*Commented part of allocation of pbufs need to check whether its true*/
for(pbuf_cnt = 0U;pbuf_cnt < MAX_RX_PBUF_ALLOC;pbuf_cnt++)
{
/*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are assigned in this driver" */
p = pbuf_array[pbuf_cnt];
/*SAFETYMCUSW 439 S MR:11.3 <APPROVED> "RHS is a pointer value required to be stored. - Advisory as per MISRA" */
/*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are assigned in this driver" */
curr_bd->bufptr = (uint32)p;
/*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are assigned in this driver" */
curr_bd->bufoff_len = MAX_TRANSFER_UNIT;
/*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are assigned in this driver" */
curr_bd->flags_pktlen = EMAC_BUF_DESC_OWNER;
if (pbuf_cnt == (MAX_RX_PBUF_ALLOC - 1U))
{
/*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are assigned in this driver" */
curr_bd->next = NULL;
/*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are assigned in this driver" */
last_bd = curr_bd;
}
else
{
/*SAFETYMCUSW 567 S MR:17.1,17.4 <APPROVED> "Struct pointer used for linked list is incremented." */
curr_bd->next = (curr_bd + 1U);
/*SAFETYMCUSW 567 S MR:17.1,17.4 <APPROVED> "Struct pointer used for linked list is incremented." */
curr_bd++;
/*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are assigned in this driver" */
last_bd = curr_bd;
}
}
/*SAFETYMCUSW 134 S MR:12.2 <APPROVED> "LDRA Tool issue" */
/*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are assigned in this driver" */
last_bd->next = NULL;
/*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are assigned in this driver" */
rxch_dma->active_tail = last_bd;
}
/**
* \brief Initializes the EMAC module for transmission and reception.
*
* \param macaddr MAC Address of the Module.
* \param channel Channel Number.
*
* \return EMAC_ERR_OK if everything gets initialized
* EMAC_ERR_CONN in case of an error in connecting.
*
**/
/* SourceId : ETH_SourceId_049 */
/* DesignId : ETH_DesignId_049*/
/* Requirements : HL_ETH_SR6 */
uint32 EMACHWInit(uint8_t macaddr[6U])
{
uint32 temp, channel;
volatile uint32 phyID=0U;
volatile uint32 delay = 0xFFFU;
uint32 phyIdReadCount = 0xFFFFU;
volatile uint32 phyLinkRetries = 0xFFFFU;
hdkif_t *hdkif;
rxch_t *rxch;
uint32 retVal = EMAC_ERR_OK;
uint32 emacBase = 0U;
#if(EMAC_MII_ENABLE == 0U)
uint16 partnr_spd;
#endif
hdkif = &hdkif_data[0U];
EMACInstConfig(hdkif);
/* set MAC hardware address */
for(temp = 0U; temp < EMAC_HWADDR_LEN; temp++) {
hdkif->mac_addr[temp] = macaddr[(EMAC_HWADDR_LEN - 1U) - temp];
}
/*Initialize the EMAC, EMAC Control and MDIO modules. */
EMACInit(hdkif->emac_ctrl_base, hdkif->emac_base);
MDIOInit(hdkif->mdio_base, MDIO_FREQ_INPUT, MDIO_FREQ_OUTPUT);
/*SAFETYMCUSW 134 S MR:12.2 <APPROVED> "LDRA Tool issue" */
while(delay != 0U)
{
/*SAFETYMCUSW 134 S MR:12.2 <APPROVED> "LDRA Tool issue" */
delay--;
}
/* Set the MAC Addresses in EMAC hardware */
emacBase = hdkif->emac_base; /* MISRA Code Fix (12.2) */
EMACMACSrcAddrSet(emacBase, hdkif->mac_addr);
for(channel = 0U; channel < 8U; channel++) {
emacBase = hdkif->emac_base;
EMACMACAddrSet(emacBase, channel, hdkif->mac_addr, EMAC_MACADDR_MATCH);
}
/*SAFETYMCUSW 134 S MR:12.2 <APPROVED> "LDRA Tool issue" */
while ((phyID == 0U) && (phyIdReadCount > 0U)) {
phyID = Dp83640IDGet(hdkif->mdio_base,hdkif->phy_addr);
phyIdReadCount--;
}
if (0U == phyID) {
retVal = EMAC_ERR_CONNECT;
} else {
}
if((uint32)0U == ((MDIOPhyAliveStatusGet(hdkif->mdio_base)
>> hdkif->phy_addr) & (uint32)0x01U )) {
retVal = EMAC_ERR_CONNECT;
} else {
}
#if(EMAC_MII_ENABLE == 0U)
Dp83640PartnerSpdGet(hdkif->mdio_base, hdkif->phy_addr, &partnr_spd);
if((partnr_spd & 2U)==0U)
{
EMACRMIISpeedSet(hdkif->emac_base, EMAC_MACCONTROL_RMIISPEED);
}
#endif
if(!Dp83640LinkStatusGet(hdkif->mdio_base, (uint32)EMAC_PHYADDRESS, (uint32)phyLinkRetries)) {
retVal = EMAC_ERR_CONNECT;
} else {
}
if(EMACLinkSetup(hdkif) != EMAC_ERR_OK) {
retVal = EMAC_ERR_CONNECT;
} else {
}
/* The transmit and receive buffer descriptors are initialized here.
* Also, packet buffers are allocated to the receive buffer descriptors.
*/
EMACDMAInit(hdkif);
/* Acknowledge receive and transmit interrupts for proper interrupt pulsing*/
EMACCoreIntAck(hdkif->emac_base, (uint32)EMAC_INT_CORE0_RX);
EMACCoreIntAck(hdkif->emac_base, (uint32)EMAC_INT_CORE0_TX);
/* Enable GMII bit in the MACCONTROL Rgister*/
/*SAFETYMCUSW 139 S MR:13.7 <APPROVED> "Parameter is taken as input from GUI." */
EMACMIIEnable(hdkif->emac_base);
/* Enable Broadcast if enabled in the GUI. */
/*SAFETYMCUSW 139 S MR:13.7 <APPROVED> "Parameter is taken as input from GUI." */
#if(EMAC_BROADCAST_ENABLE)
EMACRxBroadCastEnable(hdkif->emac_base, (uint32)EMAC_CHANNELNUMBER);
#else
/*SAFETYMCUSW 1 J MR:14.1 <APPROVED> "If condition parameter is taken as input from GUI." */
/*SAFETYMCUSW 1 J MR:14.1 <APPROVED> "If condition parameter is taken as input from GUI." */
EMACRxBroadCastDisable(hdkif->emac_base, (uint32)EMAC_CHANNELNUMBER);
#endif
/* Enable Broadcast if enabled in the GUI. */
/*SAFETYMCUSW 139 S MR:13.7 <APPROVED> "Parameter is taken as input from GUI." */
#if(EMAC_UNICAST_ENABLE)
EMACRxUnicastSet(hdkif->emac_base, (uint32)EMAC_CHANNELNUMBER);
#else
/*SAFETYMCUSW 1 J MR:14.1 <APPROVED> "If condition parameter is taken as input from GUI." */
EMACRxUnicastClear(hdkif->emac_base, (uint32)EMAC_CHANNELNUMBER);
#endif
/*Enable Full Duplex or Half-Duplex mode based on GUI Input. */
/*SAFETYMCUSW 139 S MR:13.7 <APPROVED> "Parameter is taken as input from GUI." */
#if (EMAC_FULL_DUPLEX_ENABLE)
EMACDuplexSet(EMAC_0_BASE, (uint32)EMAC_DUPLEX_FULL);
#else
/*SAFETYMCUSW 1 J MR:14.1 <APPROVED> "If condition arameter is taken as input from GUI." */
EMACDuplexSet(EMAC_0_BASE, (uint32)EMAC_DUPLEX_HALF);
#endif
/* Enable Loopback based on GUI Input */
/*SAFETYMCUSW 139 S MR:13.7 <APPROVED> "Parameter is taken as input from GUI." */
#if(EMAC_LOOPBACK_ENABLE)
EMACEnableLoopback(hdkif->emac_base);
#else
/*SAFETYMCUSW 1 J MR:14.1 <APPROVED> "If condition parameter is taken as input from GUI." */
EMACDisableLoopback(hdkif->emac_base);
#endif
/* Enable Transmit and Transmit Interrupt */
/*SAFETYMCUSW 139 S MR:13.7 <APPROVED> "Parameter is taken as input from GUI." */
#if(EMAC_TX_ENABLE)
EMACTxEnable(hdkif->emac_base);
EMACTxIntPulseEnable(hdkif->emac_base, hdkif->emac_ctrl_base, (uint32)EMAC_CHANNELNUMBER, (uint32)EMAC_CHANNELNUMBER);
#else
/*SAFETYMCUSW 1 J MR:14.1 <APPROVED> "If condition parameter is taken as input from GUI." */
/*SAFETYMCUSW 1 J MR:14.1 <APPROVED> "If condition parameter is taken as input from GUI." */
EMACTxDisable(hdkif->emac_base);
EMACTxIntPulseDisable(hdkif->emac_base, hdkif->emac_ctrl_base, (uint32)EMAC_CHANNELNUMBER, (uint32)EMAC_CHANNELNUMBER);
#endif
/* Enable Receive and Receive Interrupt. Then start receiving by writing to the HDP register. */
/*SAFETYMCUSW 139 S MR:13.7 <APPROVED> "Parameter is taken as input from GUI." */
#if(EMAC_RX_ENABLE)
EMACNumFreeBufSet(hdkif->emac_base,(uint32)EMAC_CHANNELNUMBER , (uint32)MAX_RX_PBUF_ALLOC);
EMACRxEnable(hdkif->emac_base);
EMACRxIntPulseEnable(hdkif->emac_base, hdkif->emac_ctrl_base, (uint32)EMAC_CHANNELNUMBER, (uint32)EMAC_CHANNELNUMBER);
rxch = &(hdkif->rxchptr);
/* Write to the RX HDP for channel 0 */
/*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are assigned in this driver" */
EMACRxHdrDescPtrWrite(hdkif->emac_base, (uint32)rxch->active_head, (uint32)EMAC_CHANNELNUMBER);
#else
/*SAFETYMCUSW 1 J MR:14.1 <APPROVED> "If condition parameter is taken as input from GUI." */
/*SAFETYMCUSW 1 J MR:14.1 <APPROVED> "If condition parameter is taken as input from GUI." */
EMACRxDisable(hdkif->emac_base);
EMACRxIntPulseDisable(hdkif->emac_base, hdkif->emac_ctrl_base, (uint32)EMAC_CHANNELNUMBER, (uint32)EMAC_CHANNELNUMBER);
#endif
return retVal;
}
/**
* 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. That is, one pbuf can span more than one tx buffer descriptors
*
* @param hdkif network interface structure
* @param pbuf the pbuf structure which contains the data to be sent using EMAC
* @return boolean.
* -Returns FALSE if a Null pointer was passed for transmission
* -Returns TRUE if valid data is sent and is transmitted.
*/
/* SourceId : ETH_SourceId_050 */
/* DesignId : ETH_DesignId_050*/
/* Requirements : HL_ETH_SR31 */
boolean EMACTransmit(hdkif_t *hdkif, pbuf_t *pbuf)
{
txch_t *txch;
pbuf_t *q;
uint16 totLen;
uint16 qLen;
volatile emac_tx_bd_t *curr_bd,*active_head, *bd_end;
boolean retValue = FALSE;
if((pbuf != NULL) && (hdkif != NULL))
{
txch = &(hdkif->txchptr);
/* Get the buffer descriptor which is free to transmit */
/*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are assigned in this driver" */
curr_bd = txch->free_head;
/*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are assigned in this driver" */
bd_end = curr_bd;
/*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are assigned in this driver" */
active_head = curr_bd;
/* Update the total packet length */
/*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are assigned in this driver" */
curr_bd->flags_pktlen &= (~((uint32)0xFFFFU));
/*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are assigned in this driver" */
totLen = pbuf->tot_len;
curr_bd->flags_pktlen |= (uint32)(totLen);
/* Indicate the start of the packet */
/*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are assigned in this driver" */
curr_bd->flags_pktlen |= (EMAC_BUF_DESC_SOP | EMAC_BUF_DESC_OWNER);
/* Copy pbuf information into TX buffer descriptors */
q = pbuf;
while(q != NULL)
{
/* Initialize the buffer pointer and length */
/*SAFETYMCUSW 439 S MR:11.3 <APPROVED> "RHS is a pointer value required to be stored. - Advisory as per MISRA" */
/*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are assigned in this driver" */
curr_bd->bufptr = (uint32)(q->payload);
/*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are assigned in this driver" */
qLen = q->len;
curr_bd->bufoff_len = ((uint32)(qLen) & 0xFFFFU);
/*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are assigned in this driver" */
bd_end = curr_bd;
/*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are assigned in this driver" */
curr_bd = curr_bd->next;
q = q->next;
}
/* Indicate the start and end of the packet */
/*SAFETYMCUSW 134 S MR:12.2 <APPROVED> "LDRA Tool issue" */
/*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are assigned in this driver" */
bd_end->next = NULL;
/*SAFETYMCUSW 134 S MR:12.2 <APPROVED> "LDRA Tool issue" */
bd_end->flags_pktlen |= EMAC_BUF_DESC_EOP;
/*SAFETYMCUSW 71 S MR:17.6 <APPROVED> "Assigned pointer value has required scope." */
txch->free_head = curr_bd;
/* For the first time, write the HDP with the filled bd */
if(txch->active_tail == NULL) {
/*SAFETYMCUSW 439 S MR:11.3 <APPROVED> "Address stored in pointer is passed as as an int parameter. - Advisory as per MISRA" */
/*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are assigned in this driver" */
EMACTxHdrDescPtrWrite(hdkif->emac_base, (uint32)(active_head), (uint32)EMAC_CHANNELNUMBER);
}
/*
* Chain the bd's. If the DMA engine, already reached the end of the chain,
* the EOQ will be set. In that case, the HDP shall be written again.
*/
else {
/*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are assigned in this driver" */
curr_bd = txch->active_tail;
/* Wait for the EOQ bit is set */
/*SAFETYMCUSW 28 D MR:NA <APPROVED> "Hardware status bit read check" */
/*SAFETYMCUSW 134 S MR:12.2 <APPROVED> "LDRA Tool issue" */
/*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are assigned in this driver" */
while (EMAC_BUF_DESC_EOQ != (curr_bd->flags_pktlen & EMAC_BUF_DESC_EOQ))
{
}
/* Don't write to TXHDP0 until it turns to zero */
/*SAFETYMCUSW 28 D MR:NA <APPROVED> "Hardware status bit read check" */
/*SAFETYMCUSW 134 S MR:12.2 <APPROVED> "LDRA Tool issue" */
while (((uint32)0U != *((uint32 *)0xFCF78600U)))
{
}
/*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are assigned in this driver" */
curr_bd->next = active_head;
/*SAFETYMCUSW 134 S MR:12.2 <APPROVED> "LDRA Tool issue" */
/*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are assigned in this driver" */
if (EMAC_BUF_DESC_EOQ == (curr_bd->flags_pktlen & EMAC_BUF_DESC_EOQ)) {
/* Write the Header Descriptor Pointer and start DMA */
/*SAFETYMCUSW 439 S MR:11.3 <APPROVED> "Address stored in pointer is passed as as an int parameter. - Advisory as per MISRA" */
/*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are assigned in this driver" */
EMACTxHdrDescPtrWrite(hdkif->emac_base, (uint32)(active_head), (uint32)EMAC_CHANNELNUMBER);
}
}
/*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are assigned in this driver" */
txch->active_tail = bd_end;
retValue = TRUE;
}
else
{
retValue = FALSE;
}
return retValue;
}
/**
* Function for processing Tx buffer descriptors.
*
* @param hdkif interface structure
* @return none
*/
/* SourceId : ETH_SourceId_051 */
/* DesignId : ETH_DesignId_051*/
/* Requirements : HL_ETH_SR15 */
void EMACTxIntHandler(hdkif_t *hdkif)
{
txch_t *txch_int;
volatile emac_tx_bd_t *curr_bd, *next_bd_to_process;
txch_int = &(hdkif->txchptr);
/*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are assigned in this driver" */
next_bd_to_process = txch_int->next_bd_to_process;
/*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are assigned in this driver" */
curr_bd = next_bd_to_process;
/* Check for correct start of packet */
/*SAFETYMCUSW 134 S MR:12.2 <APPROVED> "LDRA Tool issue" */
/*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are assigned in this driver" */
while(((curr_bd->flags_pktlen) & EMAC_BUF_DESC_SOP) == EMAC_BUF_DESC_SOP) {
/* Make sure that the transmission is over */
/*SAFETYMCUSW 28 D MR:NA <APPROVED> "Hardware status bit read check" */
/*SAFETYMCUSW 134 S MR:12.2 <APPROVED> "LDRA Tool issue" */
/*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are assigned in this driver" */
while(((curr_bd->flags_pktlen) & EMAC_BUF_DESC_OWNER) == EMAC_BUF_DESC_OWNER)
{
}
/* Traverse till the end of packet is reached */
/*SAFETYMCUSW 134 S MR:12.2 <APPROVED> "LDRA Tool issue" */
/*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are assigned in this driver" */
while(((curr_bd->flags_pktlen) & EMAC_BUF_DESC_EOP) != EMAC_BUF_DESC_EOP) {
curr_bd = curr_bd->next;
}
/*SAFETYMCUSW 134 S MR:12.2 <APPROVED> "LDRA Tool issue" */
/*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are assigned in this driver" */
next_bd_to_process->flags_pktlen &= ~(EMAC_BUF_DESC_SOP);
/*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are assigned in this driver" */
curr_bd->flags_pktlen &= ~(EMAC_BUF_DESC_EOP);
/**
* If there are no more data transmitted, the next interrupt
* shall happen with the pbuf associated with the free_head
*/
/*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are assigned in this driver" */
if(curr_bd->next == NULL) {
/*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are assigned in this driver" */
txch_int->next_bd_to_process = txch_int->free_head;
}
else {
/*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are assigned in this driver" */
txch_int->next_bd_to_process = curr_bd->next;
}
/* Acknowledge the EMAC and free the corresponding pbuf */
/*SAFETYMCUSW 439 S MR:11.3 <APPROVED> "Address stored in pointer is passed as as an int parameter. - Advisory as per MISRA" */
/*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are assigned in this driver" */
/*SAFETYMCUSW 344 S MR:11.5 <APPROVED> "Address stored in pointer is passed as as an int parameter." */
EMACTxCPWrite(hdkif->emac_base, (uint32)EMAC_CHANNELNUMBER, (uint32)curr_bd);
/*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are assigned in this driver" */
next_bd_to_process = txch_int->next_bd_to_process;
/*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are assigned in this driver" */
curr_bd = next_bd_to_process;
}
}
/**
* Function for processing received packets.
*
* @param hdkif interface structure
* @return none
*/
/* SourceId : ETH_SourceId_052 */
/* DesignId : ETH_DesignId_052*/
/* Requirements : HL_ETH_SR31 */
void EMACReceive(hdkif_t *hdkif)
{
rxch_t *rxch_int;
volatile emac_rx_bd_t *curr_bd, *curr_tail, *last_bd;
/* The receive structure that holds data about a particular receive channel */
rxch_int = &(hdkif->rxchptr);
/* Get the buffer descriptors which contain the earliest filled data */
/*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are assigned in this driver" */
curr_bd = rxch_int->active_head;
/*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are assigned in this driver" */
last_bd = rxch_int->active_tail;
/**
* Process the descriptors as long as data is available
* when the DMA is receiving data, SOP flag will be set
*/
/*SAFETYMCUSW 28 D MR:NA <APPROVED> "Hardware status bit read check" */
/*SAFETYMCUSW 134 S MR:12.2 <APPROVED> "LDRA Tool issue" */
/*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are assigned in this driver" */
while((curr_bd->flags_pktlen & EMAC_BUF_DESC_SOP) == EMAC_BUF_DESC_SOP) {
/* Start processing once the packet is loaded */
/*SAFETYMCUSW 134 S MR:12.2 <APPROVED> "LDRA Tool issue" */
/*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are assigned in this driver" */
if((curr_bd->flags_pktlen & EMAC_BUF_DESC_OWNER)
!= EMAC_BUF_DESC_OWNER) {
/* this bd chain will be freed after processing */
/*SAFETYMCUSW 71 S MR:17.6 <APPROVED> "Assigned pointer value has required scope." */
/*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are assigned in this driver" */
rxch_int->free_head = curr_bd;
/* Get the total length of the packet. curr_bd points to the start
* of the packet.
*/
/*
* The loop runs till it reaches the end of the packet.
*/
/*SAFETYMCUSW 134 S MR:12.2 <APPROVED> "LDRA Tool issue" */
/*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are assigned in this driver" */
while((curr_bd->flags_pktlen & EMAC_BUF_DESC_EOP)!= EMAC_BUF_DESC_EOP)
{
/*Update the flags for the descriptor again and the length of the buffer*/
/*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are assigned in this driver" */
curr_bd->flags_pktlen = (uint32)EMAC_BUF_DESC_OWNER;
/*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are assigned in this driver" */
curr_bd->bufoff_len = (uint32)MAX_TRANSFER_UNIT;
/*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are assigned in this driver" */
last_bd = curr_bd;
/*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are assigned in this driver" */
curr_bd = curr_bd->next;
}
/* Updating the last descriptor (which contained the EOP flag) */
/*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are assigned in this driver" */
curr_bd->flags_pktlen = (uint32)EMAC_BUF_DESC_OWNER;
/*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are assigned in this driver" */
curr_bd->bufoff_len = (uint32)MAX_TRANSFER_UNIT;
/*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are assigned in this driver" */
last_bd = curr_bd;
/*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are assigned in this driver" */
curr_bd = curr_bd->next;
/* Acknowledge that this packet is processed */
/*SAFETYMCUSW 439 S MR:11.3 <APPROVED> "Address stored in pointer is passed as as an int parameter. - Advisory as per MISRA" */
/*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are assigned in this driver" */
EMACRxCPWrite(hdkif->emac_base, (uint32)EMAC_CHANNELNUMBER, (uint32)last_bd);
/* The next buffer descriptor is the new head of the linked list. */
/*SAFETYMCUSW 71 S MR:17.6 <APPROVED> "Assigned pointer value has required scope." */
/*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are assigned in this driver" */
rxch_int->active_head = curr_bd;
/* The processed descriptor is now the tail of the linked list. */
/*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are assigned in this driver" */
curr_tail = rxch_int->active_tail;
/*SAFETYMCUSW 134 S MR:12.2 <APPROVED> "LDRA Tool issue" */
/*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are assigned in this driver" */
curr_tail->next = rxch_int->free_head;
/* The last element in the already processed Rx descriptor chain is now the end of list. */
/*SAFETYMCUSW 134 S MR:12.2 <APPROVED> "LDRA Tool issue" */
/*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are assigned in this driver" */
last_bd->next = NULL;
/**
* Check if the reception has ended. If the EOQ flag is set, the NULL
* Pointer is taken by the DMA engine. So we need to write the RX HDP
* with the next descriptor.
*/
/*SAFETYMCUSW 134 S MR:12.2 <APPROVED> "LDRA Tool issue" */
/*SAFETYMCUSW 134 S MR:12.2 <APPROVED> "LDRA Tool issue" */
/*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are assigned in this driver" */
if((curr_tail->flags_pktlen & EMAC_BUF_DESC_EOQ) == EMAC_BUF_DESC_EOQ) {
/*SAFETYMCUSW 439 S MR:11.3 <APPROVED> "Address stored in pointer is passed as as an int parameter. - Advisory as per MISRA" */
/*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are assigned in this driver" */
EMACRxHdrDescPtrWrite(hdkif->emac_base, (uint32)(rxch_int->free_head), (uint32)EMAC_CHANNELNUMBER);
}
/*SAFETYMCUSW 71 S MR:17.6 <APPROVED> "Assigned pointer value has required scope." */
/*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are assigned in this driver" */
/*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are assigned in this driver" */
rxch_int->free_head = curr_bd;
rxch_int->active_tail = last_bd;
}
}
}
/** @fn void EMACGetConfigValue(emac_config_reg_t *config_reg, config_value_type_t type)
* @brief Get the initial or current values of the configuration registers
*
* @param[in] *config_reg: pointer to the struct to which the initial or current
* value of the configuration registers need to be stored
* @param[in] type: whether initial or current value of the configuration registers need to be stored
* - InitialValue: initial value of the configuration registers will be stored
* in the struct pointed by config_reg
* - CurrentValue: initial value of the configuration registers will be stored
* in the struct pointed by config_reg
*
* This function will copy the initial or current value (depending on the parameter 'type')
* of the configuration registers to the struct pointed by config_reg
*
*/
/* SourceId : ETH_SourceId_053 */
/* DesignId : ETH_DesignId_053*/
/* Requirements : HL_ETH_SR52 */
void EMACGetConfigValue(emac_config_reg_t *config_reg, config_value_type_t type)
{
if (type == InitialValue)
{
config_reg->TXCONTROL = EMAC_TXCONTROL_CONFIGVALUE;
config_reg->RXCONTROL = EMAC_RXCONTROL_CONFIGVALUE;
config_reg->TXINTMASKSET = EMAC_TXINTMASKSET_CONFIGVALUE;
config_reg->TXINTMASKCLEAR = EMAC_TXINTMASKCLEAR_CONFIGVALUE;
config_reg->RXINTMASKSET = EMAC_RXINTMASKSET_CONFIGVALUE;
config_reg->RXINTMASKCLEAR = EMAC_RXINTMASKCLEAR_CONFIGVALUE;
config_reg->MACSRCADDRHI = EMAC_MACSRCADDRHI_CONFIGVALUE;
config_reg->MACSRCADDRLO = EMAC_MACSRCADDRLO_CONFIGVALUE;
config_reg->MDIOCONTROL = EMAC_MDIOCONTROL_CONFIGVALUE;
config_reg->C0RXEN = EMAC_C0RXEN_CONFIGVALUE;
config_reg->C0TXEN = EMAC_C0TXEN_CONFIGVALUE;
}
else
{
config_reg->TXCONTROL = HWREG(EMAC_0_BASE + EMAC_TXCONTROL);
config_reg->RXCONTROL = HWREG(EMAC_0_BASE + EMAC_RXCONTROL);
config_reg->TXINTMASKSET = HWREG(EMAC_0_BASE + EMAC_TXINTMASKSET);
config_reg->TXINTMASKCLEAR = HWREG(EMAC_0_BASE + EMAC_TXINTMASKCLEAR);
config_reg->RXINTMASKSET = HWREG(EMAC_0_BASE + EMAC_RXINTMASKSET);
config_reg->RXINTMASKCLEAR = HWREG(EMAC_0_BASE + EMAC_RXINTMASKCLEAR);
config_reg->MACSRCADDRHI = HWREG(EMAC_0_BASE + EMAC_MACSRCADDRHI);
config_reg->MACSRCADDRLO = HWREG(EMAC_0_BASE + EMAC_MACSRCADDRLO);
config_reg->MDIOCONTROL = HWREG(MDIO_0_BASE + MDIO_CONTROL);
config_reg->C0RXEN = HWREG(EMAC_CTRL_0_BASE + EMAC_CTRL_CnRXEN(0U));
config_reg->C0TXEN = HWREG(EMAC_CTRL_0_BASE + EMAC_CTRL_CnTXEN(0U));
}
}
/* ISR for EMAC Transmit Interrupt. Calls another handler function for processing the descriptors.
*
* @return none
* */
/*SAFETYMCUSW 69 S MR:3.4 <APPROVED> "#pragma required for interrupt handler." */
#pragma CODE_STATE(EMACTxIntISR, 32)
/*SAFETYMCUSW 69 S MR:3.4 <APPROVED> "#pragma required for interrupt handler." */
#pragma INTERRUPT(EMACTxIntISR, IRQ)
/* SourceId : ETH_SourceId_054 */
/* DesignId : ETH_DesignId_054*/
/* Requirements : HL_ETH_SR15,HL_ETH_SR33 */
void EMACTxIntISR(void)
{
hdkif_t *hdkif;
hdkif= &hdkif_data[0U];
/*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are assigned in this driver" */
/*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are assigned in this driver" */
/*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are assigned in this driver" */
/*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are assigned in this driver" */
/*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are assigned in this driver" */
/*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are assigned in this driver" */
emacTxNotification(hdkif);
/*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are assigned in this driver" */
/*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are assigned in this driver" */
/*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are assigned in this driver" */
EMACTxIntHandler(hdkif);
EMACCoreIntAck(hdkif->emac_base, (uint32)EMAC_INT_CORE0_TX);
}
/**
* ISR for Receive interrupt. Calls another function for processing the received packets.
*
* @return none
*/
/*SAFETYMCUSW 69 S MR:3.4 <APPROVED> "#pragma required for interrupt handler." */
#pragma CODE_STATE(EMACRxIntISR, 32)
/*SAFETYMCUSW 69 S MR:3.4 <APPROVED> "#pragma required for interrupt handler." */
#pragma INTERRUPT(EMACRxIntISR, IRQ)
/* SourceId : ETH_SourceId_055 */
/* DesignId : ETH_DesignId_055*/
/* Requirements : HL_ETH_SR15,HL_ETH_SR33 */
void EMACRxIntISR(void)
{
hdkif_t *hdkif;
hdkif= &hdkif_data[0U];
/* The data is received in the allocated receive descriptors starting from (&(hdkif->rxchptr))->active_head */
/*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are assigned in this driver" */
/*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are assigned in this driver" */
/*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are assigned in this driver" */
/*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are assigned in this driver" */
/*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are assigned in this driver" */
/*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are assigned in this driver" */
emacRxNotification(hdkif);
/* In this function, the filled receive buffer descriptors are freed for further usage and the receive interrupt is acknowledged. */
/*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are assigned in this driver" */
/*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are assigned in this driver" */
/*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are assigned in this driver" */
EMACReceive(hdkif);
/* Acknowledge the EMAC Core Rx Interrupts */
EMACCoreIntAck(hdkif->emac_base, (uint32)EMAC_INT_CORE0_RX);
}
/* USER CODE BEGIN (2) */
/* USER CODE END */
/***************************** End Of File ***********************************/