/**
 * @file        apm32f4xx_eth_cfg.c
 *
 * @brief       This file provides configuration support for ETH
 *
 * @version     V1.0.0
 *
 * @date        2023-12-01
 *
 * @attention
 *
 *  Copyright (C) 2023 Geehy Semiconductor
 *
 *  You may not use this file except in compliance with the
 *  GEEHY COPYRIGHT NOTICE (GEEHY SOFTWARE PACKAGE LICENSE).
 *
 *  The program is only for reference, which is distributed in the hope
 *  that it will be useful and instructional for customers to develop
 *  their software. Unless required by applicable law or agreed to in
 *  writing, the program is distributed on an "AS IS" BASIS, WITHOUT
 *  ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the GEEHY SOFTWARE PACKAGE LICENSE for the governing permissions
 *  and limitations under the License.
 */

/* Includes ***************************************************************/
#include "apm32f4xx_eth_cfg.h"

/* Private includes *******************************************************/
#include <string.h>

/* Private macro **********************************************************/

/* Private typedef ********************************************************/

/* Private variables ******************************************************/
ETH_HandleTypeDef heth1;

/* Ethernet RX DMA Descriptors */
ETH_DMADescTypeDef DMARxDescTab[ETH_RX_DESC_CNT];
/* Ethernet TX DMA Descriptors */
ETH_DMADescTypeDef DMATxDescTab[ETH_TX_DESC_CNT];

ETH_TxPacketConfig Tx_ConfigStruct;

/* Private function prototypes ********************************************/

/* External variables *****************************************************/

/* External functions *****************************************************/

/**
 * @brief  Initializes the ETH MSP
 *
 * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
 *         the configuration information for ETHERNET module
 *
 * @retval None
 */
void DAL_ETH_MspInit(ETH_HandleTypeDef *heth)
{
    GPIO_InitTypeDef GPIO_InitStruct = {0};

    if (heth->Instance == ETH)
    {
        /* Enable peripheral clock */
        __DAL_RCM_ETH_CLK_ENABLE();

        /* Enable peripheral GPIO clock */
        __DAL_RCM_GPIOA_CLK_ENABLE();
        __DAL_RCM_GPIOC_CLK_ENABLE();
        __DAL_RCM_GPIOG_CLK_ENABLE();

        /* ETH RMII pin configuration
           ETH MDC      ----> PC1
           ETH MDIO     ----> PA2
           ETH REF CLK  ----> PA1
           ETH CRS DV   ----> PA7
           ETH RXD0     ----> PC4
           ETH RXD1     ----> PC5
           ETH TX EN    ----> PG11
           ETH TXD0     ----> PG13
           ETH TXD1     ----> PG14
        */
        GPIO_InitStruct.Pin         = GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_7;
        GPIO_InitStruct.Mode        = GPIO_MODE_AF_PP;
        GPIO_InitStruct.Pull        = GPIO_NOPULL;
        GPIO_InitStruct.Speed       = GPIO_SPEED_FREQ_VERY_HIGH;
        GPIO_InitStruct.Alternate   = GPIO_AF11_ETH;
        DAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

        GPIO_InitStruct.Pin         = GPIO_PIN_1 | GPIO_PIN_4 | GPIO_PIN_5;
        GPIO_InitStruct.Mode        = GPIO_MODE_AF_PP;
        GPIO_InitStruct.Pull        = GPIO_NOPULL;
        GPIO_InitStruct.Speed       = GPIO_SPEED_FREQ_VERY_HIGH;
        GPIO_InitStruct.Alternate   = GPIO_AF11_ETH;
        DAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

        GPIO_InitStruct.Pin         = GPIO_PIN_11 | GPIO_PIN_13 | GPIO_PIN_14;
        GPIO_InitStruct.Mode        = GPIO_MODE_AF_PP;
        GPIO_InitStruct.Pull        = GPIO_NOPULL;
        GPIO_InitStruct.Speed       = GPIO_SPEED_FREQ_VERY_HIGH;
        GPIO_InitStruct.Alternate   = GPIO_AF11_ETH;
        DAL_GPIO_Init(GPIOG, &GPIO_InitStruct);
    }
}

/**
 * @brief  DeInitializes ETH MSP
 *
 * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
 *         the configuration information for ETHERNET module
 *
 * @retval None
 */
void DAL_ETH_MspDeInit(ETH_HandleTypeDef *heth)
{
    if (heth->Instance == ETH)
    {
        /* Disable peripheral clock */
        __DAL_RCM_ETH_CLK_DISABLE();

        /* SDIO GPIO configuration */
        DAL_GPIO_DeInit(GPIOA, GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_7);
        DAL_GPIO_DeInit(GPIOC, GPIO_PIN_1 | GPIO_PIN_4 | GPIO_PIN_5);
        DAL_GPIO_DeInit(GPIOG, GPIO_PIN_11 | GPIO_PIN_13 | GPIO_PIN_14);
    }
}

/**
 * @brief   ETH configuration
 *
 * @param   None
 *
 * @retval  Configure status
 */
DAL_StatusTypeDef DAL_ETH_Config(void)
{
    /* ETH MAC address */
    static uint8_t macAddress[6] =
    {
        ETH_MAC_ADDR_0,
        ETH_MAC_ADDR_1,
        ETH_MAC_ADDR_2,
        ETH_MAC_ADDR_3,
        ETH_MAC_ADDR_4,
        ETH_MAC_ADDR_5,
    };

    heth1.Instance              = ETH;
    heth1.Init.MACAddr          = &macAddress[0];
    heth1.Init.MediaInterface   = DAL_ETH_RMII_MODE;
    heth1.Init.TxDesc           = DMATxDescTab;
    heth1.Init.RxDesc           = DMARxDescTab;
    heth1.Init.RxBuffLen        = ETH_MAX_PACKET_SIZE;
    if (DAL_ETH_Init(&heth1) != DAL_OK)
    {
        Error_Handler();
    }

    memset(&Tx_ConfigStruct, 0U , sizeof(ETH_TxPacketConfig));
    Tx_ConfigStruct.Attributes      = ETH_TX_PACKETS_FEATURES_CSUM | ETH_TX_PACKETS_FEATURES_CRCPAD;
    Tx_ConfigStruct.ChecksumCtrl    = ETH_CHECKSUM_IPHDR_PAYLOAD_INSERT_PHDR_CALC;
    Tx_ConfigStruct.CRCPadCtrl      = ETH_CRC_PAD_INSERT;

    return DAL_OK;
}
