AT32F435_437_Firmware_Library/libraries/drivers/src/at32f435_437_emac.c

2310 lines
56 KiB
C

/**
**************************************************************************
* @file at32f435_437_emac.c
* @version v2.0.9
* @date 2022-06-28
* @brief contains all the functions for the emac firmware library
**************************************************************************
* Copyright notice & Disclaimer
*
* The software Board Support Package (BSP) that is made available to
* download from Artery official website is the copyrighted work of Artery.
* Artery authorizes customers to use, copy, and distribute the BSP
* software and its related documentation for the purpose of design and
* development in conjunction with Artery microcontrollers. Use of the
* software is governed by this copyright notice and the following disclaimer.
*
* THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES,
* GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS,
* TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR
* STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS,
* INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
*
**************************************************************************
*/
#include "at32f435_437_conf.h"
/** @addtogroup AT32F435_437_periph_driver
* @{
*/
/** @defgroup EMAC
* @brief EMAC driver modules
* @{
*/
#ifdef EMAC_MODULE_ENABLED
/** @defgroup EMAC_private_functions
* @{
*/
#if defined (EMAC_BASE)
/**
* @brief global pointers on tx and rx descriptor used to track transmit and receive descriptors
*/
emac_dma_desc_type *dma_tx_desc_to_set;
emac_dma_desc_type *dma_rx_desc_to_get;
/* emac private function */
static void emac_delay(uint32_t delay);
/**
* @brief deinitialize the emac peripheral registers to their default reset values.
* @param none
* @retval none
*/
void emac_reset(void)
{
crm_periph_reset(CRM_EMAC_PERIPH_RESET, TRUE);
crm_periph_reset(CRM_EMAC_PERIPH_RESET, FALSE);
}
/**
* @brief initialize emac control structure
* @param emac_control_config_type
* @retval none
*/
void emac_control_para_init(emac_control_config_type *control_para)
{
control_para->auto_nego = EMAC_AUTO_NEGOTIATION_OFF;
control_para->auto_pad_crc_strip = FALSE;
control_para->back_off_limit = EMAC_BACKOFF_LIMIT_0;
control_para->carrier_sense_disable = FALSE;
control_para->deferral_check = FALSE;
control_para->duplex_mode = EMAC_HALF_DUPLEX;
control_para->fast_ethernet_speed = EMAC_SPEED_10MBPS;
control_para->interframe_gap = EMAC_INTERFRAME_GAP_96BIT;
control_para->ipv4_checksum_offload = FALSE;
control_para->jabber_disable = FALSE;
control_para->loopback_mode = FALSE;
control_para->receive_own_disable = FALSE;
control_para->retry_disable = FALSE;
control_para->watchdog_disable = FALSE;
}
/**
* @brief according to hclk to set mdc clock frequency.
* @param none
* @retval none
*/
void emac_clock_range_set(void)
{
uint8_t bits_value = 0;
crm_clocks_freq_type clocks_freq = {0};
/* clear clock range bits */
EMAC->miiaddr_bit.cr = bits_value;
crm_clocks_freq_get(&clocks_freq);
if((clocks_freq.ahb_freq >= EMAC_HCLK_BORDER_20MHZ) && (clocks_freq.ahb_freq < EMAC_HCLK_BORDER_35MHZ))
{
bits_value = EMAC_CLOCK_RANGE_20_TO_35;
}
else if((clocks_freq.ahb_freq >= EMAC_HCLK_BORDER_35MHZ) && (clocks_freq.ahb_freq < EMAC_HCLK_BORDER_60MHZ))
{
bits_value = EMAC_CLOCK_RANGE_35_TO_60;
}
else if((clocks_freq.ahb_freq >= EMAC_HCLK_BORDER_60MHZ) && (clocks_freq.ahb_freq < EMAC_HCLK_BORDER_100MHZ))
{
bits_value = EMAC_CLOCK_RANGE_60_TO_100;
}
else if((clocks_freq.ahb_freq >= EMAC_HCLK_BORDER_100MHZ) && (clocks_freq.ahb_freq < EMAC_HCLK_BORDER_150MHZ))
{
bits_value = EMAC_CLOCK_RANGE_100_TO_150;
}
else if((clocks_freq.ahb_freq >= EMAC_HCLK_BORDER_150MHZ) && (clocks_freq.ahb_freq < EMAC_HCLK_BORDER_250MHZ))
{
bits_value = EMAC_CLOCK_RANGE_150_TO_250;
}
else if((clocks_freq.ahb_freq >= EMAC_HCLK_BORDER_250MHZ) && (clocks_freq.ahb_freq <= EMAC_HCLK_BORDER_288MHZ))
{
bits_value = EMAC_CLOCK_RANGE_250_TO_288;
}
EMAC->miiaddr_bit.cr = bits_value;
}
/**
* @brief configure emac control setting.
* @param control_struct: control setting of mac control register.
* @retval none
*/
void emac_control_config(emac_control_config_type *control_struct)
{
emac_deferral_check_set(control_struct->deferral_check);
emac_backoff_limit_set(control_struct->back_off_limit);
emac_auto_pad_crc_stripping_set(control_struct->auto_pad_crc_strip);
emac_retry_disable(control_struct->retry_disable);
emac_ipv4_checksum_offload_set(control_struct->ipv4_checksum_offload);
emac_loopback_mode_enable(control_struct->loopback_mode);
emac_receive_own_disable(control_struct->receive_own_disable);
emac_carrier_sense_disable(control_struct->carrier_sense_disable);
emac_interframe_gap_set(control_struct->interframe_gap);
emac_jabber_disable(control_struct->jabber_disable);
emac_watchdog_disable(control_struct->watchdog_disable);
}
/**
* @brief reset emac dma
* @param none
* @retval none
*/
void emac_dma_software_reset_set(void)
{
EMAC_DMA->bm_bit.swr = 1;
}
/**
* @brief get emac dma reset status
* @param none
* @retval TRUE of FALSE
*/
flag_status emac_dma_software_reset_get(void)
{
if(EMAC_DMA->bm_bit.swr)
{
return SET;
}
else
{
return RESET;
}
}
/**
* @brief enable emac and dma reception/transmission
* @param none
* @retval none
*/
void emac_start(void)
{
/* enable transmit state machine of the mac for transmission on the mii */
emac_trasmitter_enable(TRUE);
/* flush transmit fifo */
emac_dma_operations_set(EMAC_DMA_OPS_FLUSH_TRANSMIT_FIFO, TRUE);
/* enable receive state machine of the mac for reception from the mii */
emac_receiver_enable(TRUE);
/* start dma transmission */
emac_dma_operations_set(EMAC_DMA_OPS_START_STOP_TRANSMIT, TRUE);
/* start dma reception */
emac_dma_operations_set(EMAC_DMA_OPS_START_STOP_RECEIVE, TRUE);
}
/**
* @brief stop emac and dma reception/transmission
* @param none
* @retval none
*/
void emac_stop(void)
{
/* stop dma transmission */
emac_dma_operations_set(EMAC_DMA_OPS_START_STOP_TRANSMIT, FALSE);
/* stop dma reception */
emac_dma_operations_set(EMAC_DMA_OPS_START_STOP_RECEIVE, FALSE);
/* stop receive state machine of the mac for reception from the mii */
emac_receiver_enable(FALSE);
/* flush transmit fifo */
emac_dma_operations_set(EMAC_DMA_OPS_FLUSH_TRANSMIT_FIFO, TRUE);
/* stop transmit state machine of the mac for transmission on the mii */
emac_trasmitter_enable(FALSE);
}
/**
* @brief write phy data.
* @param address: phy address.
* @param reg: register of phy.
* @param data: value that wants to write to phy.
* @retval SUCCESS or ERROR
*/
error_status emac_phy_register_write(uint8_t address, uint8_t reg, uint16_t data)
{
uint32_t timeout = 0;
EMAC->miidt_bit.md = data;
EMAC->miiaddr_bit.pa = address;
EMAC->miiaddr_bit.mii = reg;
EMAC->miiaddr_bit.mw = 1;
EMAC->miiaddr_bit.mb = 1;
do
{
timeout++;
} while((EMAC->miiaddr_bit.mb) && (timeout < PHY_TIMEOUT));
if(timeout == PHY_TIMEOUT)
{
return ERROR;
}
return SUCCESS;
}
/**
* @brief read phy data
* @param address: phy address.
* @param reg: register of phy.
* @param data: value that is read from phy.
* @retval SUCCESS or ERROR
*/
error_status emac_phy_register_read(uint8_t address, uint8_t reg, uint16_t *data)
{
uint32_t timeout = 0;
EMAC->miiaddr_bit.pa = address;
EMAC->miiaddr_bit.mii = reg;
EMAC->miiaddr_bit.mw = 0;
EMAC->miiaddr_bit.mb = 1;
do
{
timeout++;
*data = EMAC->miidt_bit.md;
} while((EMAC->miiaddr_bit.mb) && (timeout < PHY_TIMEOUT));
if(timeout == PHY_TIMEOUT)
{
return ERROR;
}
*data = EMAC->miidt_bit.md;
return SUCCESS;
}
/**
* @brief emac receiver enable.
* @param new_state: TRUE or FALSE.
* @retval none
*/
void emac_receiver_enable(confirm_state new_state)
{
__IO uint32_t temp = 0;
EMAC->ctrl_bit.re = new_state;
temp = EMAC->ctrl;
emac_delay(1);
EMAC->ctrl = temp;
}
/**
* @brief emac transmitter enable.
* @param new_state: TRUE or FALSE.
* @retval none
*/
void emac_trasmitter_enable(confirm_state new_state)
{
__IO uint32_t temp = 0;
EMAC->ctrl_bit.te = new_state;
temp = EMAC->ctrl;
emac_delay(1);
EMAC->ctrl = temp;
}
/**
* @brief emac defferal check enable, only avalible in half-duplex mode.
* @param new_state: TRUE or FALSE.
* @retval none
*/
void emac_deferral_check_set(confirm_state new_state)
{
EMAC->ctrl_bit.dc = new_state;
}
/**
* @brief emac back-off limit, only avalible in half-duplex mode.
* @param slot_time: waiting time of retransmission after collision
* this parameter can be one of the following values:
* - EMAC_BACKOFF_LIMIT_0
* - EMAC_BACKOFF_LIMIT_1
* - EMAC_BACKOFF_LIMIT_2
* - EMAC_BACKOFF_LIMIT_3
* @retval none
*/
void emac_backoff_limit_set(emac_bol_type slot_time)
{
EMAC->ctrl_bit.bl = slot_time;
}
/**
* @brief set mac automatic pad/CRC stripping.
* @param new_state: TRUE or FALSE.
* @retval none
*/
void emac_auto_pad_crc_stripping_set(confirm_state new_state)
{
EMAC->ctrl_bit.acs = new_state;
}
/**
* @brief transmittion retry disable.
* @param new_state: TRUE or FALSE.
* @retval none
*/
void emac_retry_disable(confirm_state new_state)
{
EMAC->ctrl_bit.dr = new_state;
}
/**
* @brief set ipv4 checksum offload.
* @param new_state: TRUE or FALSE.
* @retval none
*/
void emac_ipv4_checksum_offload_set(confirm_state new_state)
{
EMAC->ctrl_bit.ipc = new_state;
}
/**
* @brief enable loopback mode.
* @param new_state: TRUE or FALSE.
* @retval none
*/
void emac_loopback_mode_enable(confirm_state new_state)
{
EMAC->ctrl_bit.lm = new_state;
}
/**
* @brief receive own disable.
* @param new_state: TRUE or FALSE.
* @retval none
*/
void emac_receive_own_disable(confirm_state new_state)
{
EMAC->ctrl_bit.dro = new_state;
}
/**
* @brief carrier sense disbale.
* @param new_state: TRUE or FALSE.
* @retval none
*/
void emac_carrier_sense_disable(confirm_state new_state)
{
EMAC->ctrl_bit.dcs = new_state;
}
/**
* @brief set minimum interframe gap between frames during transmission.
* @param number: interframe gap number.
* this parameter can be one of the following values:
* - EMAC_FRAME_GAP_96BIT
* - EMAC_FRAME_GAP_88BIT
* - EMAC_FRAME_GAP_80BIT
* - EMAC_FRAME_GAP_72BIT
* - EMAC_FRAME_GAP_64BIT
* - EMAC_FRAME_GAP_56BIT
* - EMAC_FRAME_GAP_48BIT
* - EMAC_FRAME_GAP_40BIT
* @retval none
*/
void emac_interframe_gap_set(emac_intergrame_gap_type number)
{
EMAC->ctrl_bit.ifg = number;
}
/**
* @brief jabber disable.
* @param new_state: TRUE or FALSE.
* @retval none
*/
void emac_jabber_disable(confirm_state new_state)
{
EMAC->ctrl_bit.jd = new_state;
}
/**
* @brief watchdog disable.
* @param new_state: TRUE or FALSE.
* @retval none
*/
void emac_watchdog_disable(confirm_state new_state)
{
EMAC->ctrl_bit.wd = new_state;
}
/**
* @brief set mac fast emac speed.
* @param speed: mac bandwidth
* this parameter can be one of the following values:
* - EMAC_SPEED_10MBPS
* - EMAC_SPEED_100MBPS
* @retval none
*/
void emac_fast_speed_set(emac_speed_type speed)
{
EMAC->ctrl_bit.fes = speed;
}
/**
* @brief set duplex mode.
* @param duplex_mode: communication mode
* this parameter can be one of the following values:
* - EMAC_HALF_DUPLEX
* - EMAC_FULL_DUPLEX
* @retval none
*/
void emac_duplex_mode_set(emac_duplex_type duplex_mode)
{
EMAC->ctrl_bit.dm = duplex_mode;
}
/**
* @brief set mac promiscuous mode.
* @param new_state: TRUE or FALSE.
* @retval none
*/
void emac_promiscuous_mode_set(confirm_state new_state)
{
EMAC->frmf_bit.pr = new_state;
}
/**
* @brief hash unicast.
* @param new_state: TRUE or FALSE.
* @retval none
*/
void emac_hash_unicast_set(confirm_state new_state)
{
EMAC->frmf_bit.huc = new_state;
}
/**
* @brief hash multicast.
* @param new_state: TRUE or FALSE.
* @retval none
*/
void emac_hash_multicast_set(confirm_state new_state)
{
EMAC->frmf_bit.hmc = new_state;
}
/**
* @brief destination address inverse filtering.
* @param new_state: TRUE or FALSE.
* @retval none
*/
void emac_dstaddr_inverse_filter_set(confirm_state new_state)
{
EMAC->frmf_bit.daif = new_state;
}
/**
* @brief pass all multicasting frames.
* @param new_state: TRUE or FALSE.
* @retval none
*/
void emac_pass_all_multicasting_set(confirm_state new_state)
{
EMAC->frmf_bit.pmc = new_state;
}
/**
* @brief broadcast frames disable.
* @param new_state: TRUE or FALSE.
* @retval none
*/
void emac_broadcast_frames_disable(confirm_state new_state)
{
EMAC->frmf_bit.dbf = new_state;
}
/**
* @brief set mac how to pass control frames.
* @param condition: set what control frame can pass filter.
* this parameter can be one of the following values:
* - EMAC_CONTROL_FRAME_PASSING_NO
* - EMAC_CONTROL_FRAME_PASSING_ALL
* - EMAC_CONTROL_FRAME_PASSING_MATCH
* @retval none
*/
void emac_pass_control_frames_set(emac_control_frames_filter_type condition)
{
EMAC->frmf_bit.pcf = condition;
}
/**
* @brief source address inverse filtering.
* @param new_state: TRUE or FALSE.
* @retval none
*/
void emac_srcaddr_inverse_filter_set(confirm_state new_state)
{
EMAC->frmf_bit.saif = new_state;
}
/**
* @brief source address filtering.
* @param new_state: TRUE or FALSE.
* @retval none
*/
void emac_srcaddr_filter_set(confirm_state new_state)
{
EMAC->frmf_bit.saf = new_state;
}
/**
* @brief mac uses hash or perfect filter.
* @param new_state: TRUE or FALSE.
* @retval none
*/
void emac_hash_perfect_filter_set(confirm_state new_state)
{
EMAC->frmf_bit.hpf = new_state;
}
/**
* @brief mac receives all frames.
* @param new_state: TRUE or FALSE.
* @retval none
*/
void emac_receive_all_set(confirm_state new_state)
{
EMAC->frmf_bit.ra = new_state;
}
/**
* @brief hash table high 32-bit.
* @param high32bits: the highest 32-bit of hash table.
* @retval none
*/
void emac_hash_table_high32bits_set(uint32_t high32bits)
{
EMAC->hth_bit.hth = high32bits;
}
/**
* @brief hash table low 32-bit.
* @param low32bits: the lowest 32-bit of hash table.
* @retval none
*/
void emac_hash_table_low32bits_set(uint32_t low32bits)
{
EMAC->htl_bit.htl = low32bits;
}
/**
* @brief mii busy status.
* @param none
* @retval SET or RESET
*/
flag_status emac_mii_busy_get(void)
{
if(EMAC->miiaddr_bit.mb) {
return SET;
}
else {
return RESET;
}
}
/**
* @brief tell phy that will be written.
* @param new_state: TRUE or FALSE.
* @retval none
*/
void emac_mii_write(confirm_state new_state)
{
EMAC->miiaddr_bit.mw = new_state;
}
/**
* @brief set flow control busy in full-duplex mode, back pressure activate in half-duplex mode.
* @param new_state: TRUE or FALSE.
* @retval none
*/
void emac_fcb_bpa_set(confirm_state new_state)
{
EMAC->fctrl_bit.fcbbpa = new_state;
}
/**
* @brief set transmit flow control.
* @param new_state: TRUE or FALSE.
* @retval none
*/
void emac_transmit_flow_control_enable(confirm_state new_state)
{
EMAC->fctrl_bit.etf = new_state;
}
/**
* @brief set receive flow control.
* @param new_state: TRUE or FALSE.
* @retval none
*/
void emac_receive_flow_control_enable(confirm_state new_state)
{
EMAC->fctrl_bit.erf = new_state;
}
/**
* @brief set unicast pause frame detect.
* @param new_state: TRUE or FALSE.
* @retval none
*/
void emac_unicast_pause_frame_detect(confirm_state new_state)
{
EMAC->fctrl_bit.dup = new_state;
}
/**
* @brief set pause low threshold.
* @param pasue_threshold: pause slot time.
* this parameter can be one of the following values:
* - EMAC_PAUSE_4_SLOT_TIME
* - EMAC_PAUSE_28_SLOT_TIME
* - EMAC_PAUSE_144_SLOT_TIME
* - EMAC_PAUSE_256_SLOT_TIME
* @retval none
*/
void emac_pause_low_threshold_set(emac_pause_slot_threshold_type pasue_threshold)
{
EMAC->fctrl_bit.plt = pasue_threshold;
}
/**
* @brief set zero-quanta pause disable.
* @param new_state: TRUE or FALSE.
* @retval none
*/
void emac_zero_quanta_pause_disable(confirm_state new_state)
{
EMAC->fctrl_bit.dzqp = new_state;
}
/**
* @brief set pause time.
* @param pause_time: time slots to pause transmit frame.
* @retval none
*/
void emac_pause_time_set(uint16_t pause_time)
{
EMAC->fctrl_bit.pt = pause_time;
}
/**
* @brief identify coming vlan frame field with setting value.
* @param identifier: it will be compared with coming frame.
* @retval none
*/
void emac_vlan_tag_identifier_set(uint16_t identifier)
{
EMAC->vlt_bit.vti = identifier;
}
/**
* @brief set 12-bit vlan identifier.
* @param new_state: TRUE or FALSE.
* @retval none
*/
void emac_vlan_tag_comparison_set(confirm_state new_state)
{
EMAC->vlt_bit.etv = new_state;
}
/**
* @brief set wakeup frame.
* @param value: it will be written to eight non transparent registers.
* @retval none
*/
void emac_wakeup_frame_set(uint32_t value)
{
EMAC->rwff = value;
}
/**
* @brief get wakeup frame.
* @param none
* @retval get value from eight non transparent registers.
*/
uint32_t emac_wakeup_frame_get(void)
{
return (EMAC->rwff);
}
/**
* @brief all frame will be droppped except wakeup frame or magic packet.
* @param new_state: TRUE or FALSE.
* @retval none
*/
void emac_power_down_set(confirm_state new_state)
{
EMAC->pmtctrlsts_bit.pd = new_state;
}
/**
* @brief magic packet enable
* @param new_state: TRUE or FALSE.
* @retval none
*/
void emac_magic_packet_enable(confirm_state new_state)
{
EMAC->pmtctrlsts_bit.emp = new_state;
}
/**
* @brief wakeup frame enable
* @param new_state: TRUE or FALSE.
* @retval none
*/
void emac_wakeup_frame_enable(confirm_state new_state)
{
EMAC->pmtctrlsts_bit.erwf = new_state;
}
/**
* @brief received magic packet
* @param none
* @retval the new state of usart_flag (SET or RESET).
*/
flag_status emac_received_magic_packet_get(void)
{
if(EMAC->pmtctrlsts_bit.rmp)
{
return SET;
}
else
{
return RESET;
}
}
/**
* @brief received wakeup frame.
* @param none
* @retval the new state of usart_flag (SET or RESET).
*/
flag_status emac_received_wakeup_frame_get(void)
{
if(EMAC->pmtctrlsts_bit.rrwf)
{
return SET;
}
else
{
return RESET;
}
}
/**
* @brief set unicast frame that passes DAF as wakeup frame.
* @param new_state: TRUE or FALSE.
* @retval none
*/
void emac_global_unicast_set(confirm_state new_state)
{
EMAC->pmtctrlsts_bit.guc = new_state;
}
/**
* @brief reset wakeup frame filter resgister
* @param new_state: TRUE or FALSE.
* @retval none
*/
void emac_wakeup_frame_filter_reset(confirm_state new_state)
{
EMAC->pmtctrlsts_bit.rwffpr = new_state;
}
/**
* @brief read interrupt status
* @param flag: specifies the flag to check.
* this parameter can be one of the following values:
* - EMAC_PMT_FLAG
* - EMAC_MMC_FLAG
* - EMAC_MMCR_FLAG
* - EMAC_MMCT_FLAG
* - EMAC_TST_FLAG
* @retval the new state of usart_flag (SET or RESET).
*/
flag_status emac_interrupt_status_read(uint32_t flag)
{
if(EMAC->ists & flag)
{
return SET;
}
else
{
return RESET;
}
}
/**
* @brief set interrupt mask
* @param mask_type: mask the interrupt signal
* this parameter can be one of the following values:
* - EMAC_INTERRUPT_PMT_MASK
* - EMAC_INTERRUPT_TST_MASK
* @param new_state: TRUE or FALSE.
* @retval none
*/
void emac_interrupt_mask_set(emac_interrupt_mask_type mask_type, confirm_state new_state)
{
switch(mask_type)
{
case EMAC_INTERRUPT_PMT_MASK:
{
EMAC->imr_bit.pim = new_state;
break;
}
case EMAC_INTERRUPT_TST_MASK:
{
EMAC->imr_bit.tim = new_state;
break;
}
}
}
/**
* @brief set local mac address
* @param address: local address for mac0
* @retval none
*/
void emac_local_address_set(uint8_t *address)
{
EMAC->a0h_bit.ma0h = (uint32_t)(address[5] << 8 | address[4]);
EMAC->a0l_bit.ma0l = (uint32_t)(address[3] << 24 | address[2] << 16 | address[1] << 8 | address[0]);
}
/**
* @brief set mac filter address
* @param mac: select which mac you want to set
* this parameter can be one of the following values:
* - EMAC_ADDRESS_FILTER_1
* - EMAC_ADDRESS_FILTER_2
* - EMAC_ADDRESS_FILTER_3
* @retval none
*/
void emac_address_filter_set(emac_address_type mac, emac_address_filter_type filter, emac_address_mask_type mask_bit, confirm_state new_state)
{
switch(mac)
{
case EMAC_ADDRESS_FILTER_1:
{
EMAC->a1h_bit.sa = filter;
EMAC->a1h_bit.mbc = mask_bit;
EMAC->a1h_bit.ae = new_state;
break;
}
case EMAC_ADDRESS_FILTER_2:
{
EMAC->a2h_bit.sa = filter;
EMAC->a2h_bit.mbc = mask_bit;
EMAC->a2h_bit.ae = new_state;
break;
}
case EMAC_ADDRESS_FILTER_3:
{
EMAC->a3h_bit.sa = filter;
EMAC->a3h_bit.mbc = mask_bit;
EMAC->a3h_bit.ae = new_state;
break;
}
}
}
/**
* @brief set transmit/receive descriptor list address
* @param transfer_type: it will be transmit or receive
* this parameter can be one of the following values:
* - EMAC_DMA_TRANSMIT
* - EMAC_DMA_RECEIVE
* @param dma_desc_tab: pointer on the first tx desc list
* @param buff: pointer on the first tx/rx buffer list
* @param buffer_count: number of the used Tx desc in the list
* @retval none
*/
void emac_dma_descriptor_list_address_set(emac_dma_tx_rx_type transfer_type, emac_dma_desc_type *dma_desc_tab, uint8_t *buff, uint32_t buffer_count)
{
uint32_t i = 0;
emac_dma_desc_type *dma_descriptor;
switch(transfer_type)
{
case EMAC_DMA_TRANSMIT:
{
dma_tx_desc_to_set = dma_desc_tab;
for(i = 0; i < buffer_count; i++)
{
dma_descriptor = dma_desc_tab + i;
dma_descriptor->status = EMAC_DMATXDESC_TCH;
dma_descriptor->buf1addr = (uint32_t)(&buff[i * EMAC_MAX_PACKET_LENGTH]);
if(i < (buffer_count - 1))
{
dma_descriptor->buf2nextdescaddr = (uint32_t)(dma_desc_tab + i + 1);
}
else
{
dma_descriptor->buf2nextdescaddr = (uint32_t) dma_desc_tab;
}
}
EMAC_DMA->tdladdr_bit.stl = (uint32_t) dma_desc_tab;
break;
}
case EMAC_DMA_RECEIVE:
{
dma_rx_desc_to_get = dma_desc_tab;
for(i = 0; i < buffer_count; i++)
{
dma_descriptor = dma_desc_tab + i;
dma_descriptor->status = EMAC_DMARXDESC_OWN;
dma_descriptor->controlsize = EMAC_DMARXDESC_RCH | (uint32_t)EMAC_MAX_PACKET_LENGTH;
dma_descriptor->buf1addr = (uint32_t)(&buff[i * EMAC_MAX_PACKET_LENGTH]);
if(i < (buffer_count - 1))
{
dma_descriptor->buf2nextdescaddr = (uint32_t)(dma_desc_tab + i + 1);
}
else
{
dma_descriptor->buf2nextdescaddr = (uint32_t) dma_desc_tab;
}
}
EMAC_DMA->rdladdr_bit.srl = (uint32_t) dma_desc_tab;
break;
}
}
}
/**
* @brief enable or disable the specified dma rx descriptor receive interrupt
* @param dma_rx_desc: pointer on a rx desc.
* @param new_state: new state of the specified dma rx descriptor interrupt.
* this parameter can be one of the following values:
* - TRUE
* - FALSE.
* @retval none
*/
void emac_dma_rx_desc_interrupt_config(emac_dma_desc_type *dma_rx_desc, confirm_state new_state)
{
if (new_state != FALSE)
{
/* enable the dma rx desc receive interrupt */
dma_rx_desc->controlsize &= (~(uint32_t)EMAC_DMARXDESC_DIC);
}
else
{
/* disable the dma rx desc receive interrupt */
dma_rx_desc->controlsize |= EMAC_DMARXDESC_DIC;
}
}
/**
* @brief get transmit/receive descriptor list address
* @param transfer_type: it will be transmit or receive
* this parameter can be one of the following values:
* - EMAC_DMA_TRANSMIT
* - EMAC_DMA_RECEIVE
* @retval transmit/receive descriptor list address
*/
uint32_t emac_dma_descriptor_list_address_get(emac_dma_tx_rx_type transfer_type)
{
switch(transfer_type)
{
case EMAC_DMA_TRANSMIT:
{
return (EMAC_DMA->tdladdr_bit.stl);
}
case EMAC_DMA_RECEIVE:
{
return (EMAC_DMA->rdladdr_bit.srl);
}
}
return 0;
}
/**
* @brief get the size of received the received packet.
* @param none
* @retval received packet size
*/
uint32_t emac_received_packet_size_get(void)
{
uint32_t frame_length = 0;
if(((dma_rx_desc_to_get->status & EMAC_DMARXDESC_OWN) == (uint32_t)RESET) &&
((dma_rx_desc_to_get->status & EMAC_DMATXDESC_ES) == (uint32_t)RESET) &&
((dma_rx_desc_to_get->status & EMAC_DMARXDESC_LS) != (uint32_t)RESET) &&
((dma_rx_desc_to_get->status & EMAC_DMARXDESC_FS) != (uint32_t)RESET))
{
frame_length = emac_dmarxdesc_frame_length_get(dma_rx_desc_to_get);
}
return frame_length;
}
/**
* @brief get the specified dma rx descsriptor frame length.
* @param dma_rx_desc: pointer on a dma rx descriptor
* @retval the rx descriptor received frame length.
*/
uint32_t emac_dmarxdesc_frame_length_get(emac_dma_desc_type *dma_rx_desc)
{
return ((dma_rx_desc->status & EMAC_DMARXDESC_FL) >> EMAC_DMARXDESC_FRAME_LENGTHSHIFT);
}
/**
* @brief init emac dma parameters
* @param emac_dma_config_type
* @retval none
*/
void emac_dma_para_init(emac_dma_config_type *control_para)
{
control_para->aab_enable = FALSE;
control_para->da_enable = FALSE;
control_para->desc_skip_length = 0;
control_para->dt_disable = FALSE;
control_para->fb_enable = FALSE;
control_para->fef_enable = FALSE;
control_para->flush_rx_disable = FALSE;
control_para->fugf_enable = FALSE;
control_para->osf_enable = FALSE;
control_para->priority_ratio = EMAC_DMA_1_RX_1_TX;
control_para->rsf_enable = FALSE;
control_para->rx_dma_pal = EMAC_DMA_PBL_1;
control_para->rx_threshold = EMAC_DMA_RX_THRESHOLD_64_BYTES;
control_para->tsf_enable = FALSE;
control_para->tx_dma_pal = EMAC_DMA_PBL_1;
control_para->tx_threshold = EMAC_DMA_TX_THRESHOLD_64_BYTES;
control_para->usp_enable = FALSE;
}
/**
* @brief configure emac dma
* @param emac_dma_config_type
* @retval none
*/
void emac_dma_config(emac_dma_config_type *control_para)
{
EMAC_DMA->bm_bit.aab = control_para->aab_enable;
EMAC_DMA->bm_bit.dsl = control_para->desc_skip_length;
EMAC_DMA->bm_bit.rdp = control_para->rx_dma_pal;
EMAC_DMA->bm_bit.pbl = control_para->tx_dma_pal;
EMAC_DMA->bm_bit.fb = control_para->fb_enable;
EMAC_DMA->bm_bit.usp = control_para->usp_enable;
EMAC_DMA->bm_bit.da = control_para->da_enable;
EMAC_DMA->bm_bit.pr = control_para->priority_ratio;
EMAC_DMA->opm_bit.dt = control_para->dt_disable;
EMAC_DMA->opm_bit.rsf = control_para->rsf_enable;
EMAC_DMA->opm_bit.dfrf = control_para->flush_rx_disable;
EMAC_DMA->opm_bit.tsf = control_para->tsf_enable;
EMAC_DMA->opm_bit.ttc = control_para->tx_threshold;
EMAC_DMA->opm_bit.fef = control_para->fef_enable;
EMAC_DMA->opm_bit.fugf = control_para->fugf_enable;
EMAC_DMA->opm_bit.rtc = control_para->rx_threshold;
EMAC_DMA->opm_bit.osf = control_para->osf_enable;
}
/**
* @brief set rx tx priority
* @param ratio: rx tx priority ratio
* this parameter can be one of the following values:
* - EMAC_DMA_1_RX_1_TX
* - EMAC_DMA_2_RX_1_TX
* - EMAC_DMA_3_RX_1_TX
* - EMAC_DMA_4_RX_1_TX
* @param new_state: TRUE or FALSE
* @retval none
*/
void emac_dma_arbitation_set(emac_dma_rx_tx_ratio_type ratio, confirm_state new_state)
{
EMAC_DMA->bm_bit.da = new_state;
if(new_state)
{
EMAC_DMA->bm_bit.pr = ratio;
}
}
/**
* @brief set descriptor skip mength
* @param length: descriptor skip length
* @retval none
*/
void emac_dma_descriptor_skip_length_set(uint8_t length)
{
EMAC_DMA->bm_bit.dsl = length;
}
/**
* @brief set programmable burst length
* @param tx_length: tx programmable burst length
* this parameter can be one of the following values:
* - EMAC_DMA_PBL_1
* - EMAC_DMA_PBL_2
* - EMAC_DMA_PBL_4
* - EMAC_DMA_PBL_8
* - EMAC_DMA_PBL_16
* - EMAC_DMA_PBL_32
* @param rx_length: rx programmable burst length
* this parameter can be one of the following values:
* - EMAC_DMA_PBL_1
* - EMAC_DMA_PBL_2
* - EMAC_DMA_PBL_4
* - EMAC_DMA_PBL_8
* - EMAC_DMA_PBL_16
* - EMAC_DMA_PBL_32
* @param new_state: TRUE or FALSE
* @retval none
*/
void emac_dma_separate_pbl_set(emac_dma_pbl_type tx_length, emac_dma_pbl_type rx_length, confirm_state new_state)
{
EMAC_DMA->bm_bit.usp = new_state;
EMAC_DMA->bm_bit.pbl = tx_length;
if(new_state)
{
EMAC_DMA->bm_bit.pbl = rx_length;
}
}
/**
* @brief set 8 times programmable burst length
* @param new_state: TRUE or FALSE
* @retval none
*/
void emac_dma_eight_pbl_mode_set(confirm_state new_state)
{
EMAC_DMA->bm_bit.pblx8 = new_state;
}
/**
* @brief set address-aligned beats
* @param new_state: TRUE or FALSE
* @retval none
*/
void emac_dma_address_aligned_beats_set(confirm_state new_state)
{
EMAC_DMA->bm_bit.aab = new_state;
}
/**
* @brief set transmit/receive poll demand
* @param transfer_type: it will be transmit or receive
* this parameter can be one of the following values:
* - EMAC_DMA_TRANSMIT
* - EMAC_DMA_RECEIVE
* @param value: it can be any number
* @retval none
*/
void emac_dma_poll_demand_set(emac_dma_tx_rx_type transfer_type, uint32_t value)
{
switch(transfer_type)
{
case EMAC_DMA_TRANSMIT:
{
EMAC_DMA->tpd_bit.tpd = value;
break;
}
case EMAC_DMA_RECEIVE:
{
EMAC_DMA->rpd_bit.rpd = value;
break;
}
}
}
/**
* @brief get transmit poll demand
* @param transfer_type: it will be transmit or receive
* this parameter can be one of the following values:
* - EMAC_DMA_TRANSMIT
* - EMAC_DMA_RECEIVE
* @retval current transmit descriptor
*/
uint32_t emac_dma_poll_demand_get(emac_dma_tx_rx_type transfer_type)
{
switch(transfer_type)
{
case EMAC_DMA_TRANSMIT:
{
return (EMAC_DMA->tpd_bit.tpd);
}
case EMAC_DMA_RECEIVE:
{
return (EMAC_DMA->rpd_bit.rpd);
}
}
return 0;
}
/**
* @brief get receive dma process status
* @param none
* @retval every situation it describe in RM
* this parameter can be one of the following values:
* - EMAC_DMA_RX_RESET_STOP_COMMAND
* - EMAC_DMA_RX_FETCH_DESCRIPTOR
* - EMAC_DMA_RX_WAITING_PACKET
* - EMAC_DMA_RX_DESCRIPTOR_UNAVAILABLE
* - EMAC_DMA_RX_CLOSE_DESCRIPTOR
* - EMAC_DMA_RX_FIFO_TO_HOST
*/
emac_dma_receive_process_status_type emac_dma_receive_status_get(void)
{
switch(EMAC_DMA->sts_bit.rs)
{
case EMAC_DMA_RX_RESET_STOP_COMMAND:
{
return EMAC_DMA_RX_RESET_STOP_COMMAND;
}
case EMAC_DMA_RX_FETCH_DESCRIPTOR:
{
return EMAC_DMA_RX_FETCH_DESCRIPTOR;
}
case EMAC_DMA_RX_WAITING_PACKET:
{
return EMAC_DMA_RX_WAITING_PACKET;
}
case EMAC_DMA_RX_DESCRIPTOR_UNAVAILABLE:
{
return EMAC_DMA_RX_DESCRIPTOR_UNAVAILABLE;
}
case EMAC_DMA_RX_CLOSE_DESCRIPTOR:
{
return EMAC_DMA_RX_CLOSE_DESCRIPTOR;
}
case EMAC_DMA_RX_FIFO_TO_HOST:
{
return EMAC_DMA_RX_FIFO_TO_HOST;
}
}
return EMAC_DMA_RX_RESET_STOP_COMMAND;
}
/**
* @brief get transmit dma process status
* @param none
* @retval every situation it describe in RM
* this parameter can be one of the following values:
* - EMAC_DMA_TX_RESET_STOP_COMMAND
* - EMAC_DMA_TX_FETCH_DESCRIPTOR
* - EMAC_DMA_TX_WAITING_FOR_STATUS
* - EMAC_DMA_TX_HOST_TO_FIFO
* - EMAC_DMA_TX_DESCRIPTOR_UNAVAILABLE
* - EMAC_DMA_TX_CLOSE_DESCRIPTOR
*/
emac_dma_transmit_process_status_type emac_dma_transmit_status_get(void)
{
switch(EMAC_DMA->sts_bit.ts)
{
case EMAC_DMA_TX_RESET_STOP_COMMAND:
{
return EMAC_DMA_TX_RESET_STOP_COMMAND;
}
case EMAC_DMA_TX_FETCH_DESCRIPTOR:
{
return EMAC_DMA_TX_FETCH_DESCRIPTOR;
}
case EMAC_DMA_TX_WAITING_FOR_STATUS:
{
return EMAC_DMA_TX_WAITING_FOR_STATUS;
}
case EMAC_DMA_TX_HOST_TO_FIFO:
{
return EMAC_DMA_TX_HOST_TO_FIFO;
}
case EMAC_DMA_TX_DESCRIPTOR_UNAVAILABLE:
{
return EMAC_DMA_TX_DESCRIPTOR_UNAVAILABLE;
}
case EMAC_DMA_TX_CLOSE_DESCRIPTOR:
{
return EMAC_DMA_TX_CLOSE_DESCRIPTOR;
}
}
return EMAC_DMA_TX_RESET_STOP_COMMAND;
}
/**
* @brief set dma operations
* @param ops: operations of dma
* this parameter can be one of the following values:
* - EMAC_DMA_OPS_START_STOP_RECEIVE
* - EMAC_DMA_OPS_SECOND_FRAME
* - EMAC_DMA_OPS_FORWARD_UNDERSIZED
* - EMAC_DMA_OPS_FORWARD_ERROR
* - EMAC_DMA_OPS_START_STOP_TRANSMIT
* - EMAC_DMA_OPS_FLUSH_TRANSMIT_FIFO
* - EMAC_DMA_OPS_TRANSMIT_STORE_FORWARD
* - EMAC_DMA_OPS_RECEIVE_FLUSH_DISABLE
* - EMAC_DMA_OPS_RECEIVE_STORE_FORWARD
* - EMAC_DMA_OPS_DROP_ERROR_DISABLE
* @param new_state: TRUE or FALSE
* @retval none
*/
void emac_dma_operations_set(emac_dma_operations_type ops, confirm_state new_state)
{
__IO uint32_t temp = 0;
switch(ops)
{
case EMAC_DMA_OPS_START_STOP_RECEIVE:
{
EMAC_DMA->opm_bit.ssr = new_state;
break;
}
case EMAC_DMA_OPS_SECOND_FRAME:
{
EMAC_DMA->opm_bit.osf = new_state;
break;
}
case EMAC_DMA_OPS_FORWARD_UNDERSIZED:
{
EMAC_DMA->opm_bit.fugf = new_state;
break;
}
case EMAC_DMA_OPS_FORWARD_ERROR:
{
EMAC_DMA->opm_bit.fef = new_state;
break;
}
case EMAC_DMA_OPS_START_STOP_TRANSMIT:
{
EMAC_DMA->opm_bit.sstc = new_state;
break;
}
case EMAC_DMA_OPS_FLUSH_TRANSMIT_FIFO:
{
EMAC_DMA->opm_bit.ftf = new_state;
temp = EMAC_DMA->opm;
emac_delay(1);
EMAC_DMA->opm = temp;
break;
}
case EMAC_DMA_OPS_TRANSMIT_STORE_FORWARD:
{
EMAC_DMA->opm_bit.tsf = new_state;
break;
}
case EMAC_DMA_OPS_RECEIVE_FLUSH_DISABLE:
{
EMAC_DMA->opm_bit.dfrf = new_state;
break;
}
case EMAC_DMA_OPS_RECEIVE_STORE_FORWARD:
{
EMAC_DMA->opm_bit.rsf = new_state;
break;
}
case EMAC_DMA_OPS_DROP_ERROR_DISABLE:
{
EMAC_DMA->opm_bit.dt = new_state;
break;
}
}
}
/**
* @brief set receive dma threshold
* @param value: receive threshold
* this parameter can be one of the following values:
* - EMAC_DMA_RX_THRESHOLD_64_BYTES
* - EMAC_DMA_RX_THRESHOLD_32_BYTES
* - EMAC_DMA_RX_THRESHOLD_96_BYTES
* - EMAC_DMA_RX_THRESHOLD_128_BYTES
* @retval none
*/
void emac_dma_receive_threshold_set(emac_dma_receive_threshold_type value)
{
EMAC_DMA->opm_bit.rtc = value;
}
/**
* @brief set transmit dma threshold
* @param value: transmit threshold
* this parameter can be one of the following values:
* - EMAC_DMA_TX_THRESHOLD_64_BYTES
* - EMAC_DMA_TX_THRESHOLD_128_BYTES
* - EMAC_DMA_TX_THRESHOLD_192_BYTES
* - EMAC_DMA_TX_THRESHOLD_256_BYTES
* - EMAC_DMA_TX_THRESHOLD_40_BYTES
* - EMAC_DMA_TX_THRESHOLD_32_BYTES
* - EMAC_DMA_TX_THRESHOLD_24_BYTES
* - EMAC_DMA_TX_THRESHOLD_16_BYTES
* @retval none
*/
void emac_dma_transmit_threshold_set(emac_dma_transmit_threshold_type value)
{
EMAC_DMA->opm_bit.ttc = value;
}
/**
* @brief enable dma interrupt
* @param it: interrupt type
* this parameter can be one of the following values:
* - EMAC_DMA_INTERRUPT_TX
* - EMAC_DMA_INTERRUPT_TX_STOP
* - EMAC_DMA_INTERRUPT_TX_UNAVAILABLE
* - EMAC_DMA_INTERRUPT_TX_JABBER
* - EMAC_DMA_INTERRUPT_RX_OVERFLOW
* - EMAC_DMA_INTERRUPT_TX_UNDERFLOW
* - EMAC_DMA_INTERRUPT_RX
* - EMAC_DMA_INTERRUPT_RX_UNAVAILABLE
* - EMAC_DMA_INTERRUPT_RX_STOP
* - EMAC_DMA_INTERRUPT_RX_TIMEOUT
* - EMAC_DMA_INTERRUPT_TX_EARLY
* - EMAC_DMA_INTERRUPT_FATAL_BUS_ERROR
* - EMAC_DMA_INTERRUPT_RX_EARLY
* - EMAC_DMA_INTERRUPT_ABNORMAL_SUMMARY
* - EMAC_DMA_INTERRUPT_NORMAL_SUMMARY
* @param new_state: TRUE or FALSE
* @retval none
*/
void emac_dma_interrupt_enable(emac_dma_interrupt_type it, confirm_state new_state)
{
switch(it)
{
case EMAC_DMA_INTERRUPT_TX:
{
EMAC_DMA->ie_bit.tie = new_state;
break;
}
case EMAC_DMA_INTERRUPT_TX_STOP:
{
EMAC_DMA->ie_bit.tse = new_state;
break;
}
case EMAC_DMA_INTERRUPT_TX_UNAVAILABLE:
{
EMAC_DMA->ie_bit.tue = new_state;
break;
}
case EMAC_DMA_INTERRUPT_TX_JABBER:
{
EMAC_DMA->ie_bit.tje = new_state;
break;
}
case EMAC_DMA_INTERRUPT_RX_OVERFLOW:
{
EMAC_DMA->ie_bit.ove = new_state;
break;
}
case EMAC_DMA_INTERRUPT_TX_UNDERFLOW:
{
EMAC_DMA->ie_bit.une = new_state;
break;
}
case EMAC_DMA_INTERRUPT_RX:
{
EMAC_DMA->ie_bit.rie = new_state;
break;
}
case EMAC_DMA_INTERRUPT_RX_UNAVAILABLE:
{
EMAC_DMA->ie_bit.rbue = new_state;
break;
}
case EMAC_DMA_INTERRUPT_RX_STOP:
{
EMAC_DMA->ie_bit.rse = new_state;
break;
}
case EMAC_DMA_INTERRUPT_RX_TIMEOUT:
{
EMAC_DMA->ie_bit.rwte = new_state;
break;
}
case EMAC_DMA_INTERRUPT_TX_EARLY:
{
EMAC_DMA->ie_bit.eie = new_state;
break;
}
case EMAC_DMA_INTERRUPT_FATAL_BUS_ERROR:
{
EMAC_DMA->ie_bit.fbee = new_state;
break;
}
case EMAC_DMA_INTERRUPT_RX_EARLY:
{
EMAC_DMA->ie_bit.ere = new_state;
break;
}
case EMAC_DMA_INTERRUPT_ABNORMAL_SUMMARY:
{
EMAC_DMA->ie_bit.aie = new_state;
break;
}
case EMAC_DMA_INTERRUPT_NORMAL_SUMMARY:
{
EMAC_DMA->ie_bit.nie = new_state;
break;
}
}
}
/**
* @brief get missed frames by the controller
* @param none
* @retval missed frames by the controller
*/
uint16_t emac_dma_controller_missing_frame_get(void)
{
uint16_t number = EMAC_DMA->mfbocnt_bit.mfc;
return number;
}
/**
* @brief get overflow bit for missed frame counter
* @param none
* @retval overflow bit for missed frame counter
*/
uint8_t emac_dma_missing_overflow_bit_get(void)
{
uint8_t number = EMAC_DMA->mfbocnt_bit.obmfc;
return number;
}
/**
* @brief get missed frames by the application
* @param none
* @retval missed frames by the application
*/
uint16_t emac_dma_application_missing_frame_get(void)
{
uint16_t number = EMAC_DMA->mfbocnt_bit.ofc;
return number;
}
/**
* @brief get overflow bit for FIFO overflow counter
* @param none
* @retval overflow bit for FIFO overflow counter
*/
uint8_t emac_dma_fifo_overflow_bit_get(void)
{
uint8_t number = EMAC_DMA->mfbocnt_bit.obfoc;
return number;
}
/**
* @brief get overflow bit for FIFO overflow counter
* @param transfer type: receive/transmit type
* this parameter can be one of the following values:
* - EMAC_DMA_TX_DESCRIPTOR
* - EMAC_DMA_RX_DESCRIPTOR
* - EMAC_DMA_TX_BUFFER
* - EMAC_DMA_RX_BUFFER
* @retval memory address
*/
uint32_t emac_dma_tansfer_address_get(emac_dma_transfer_address_type transfer_type)
{
uint32_t address = 0;
switch(transfer_type)
{
case EMAC_DMA_TX_DESCRIPTOR:
{
address = EMAC_DMA->ctd_bit.htdap;
break;
}
case EMAC_DMA_RX_DESCRIPTOR:
{
address = EMAC_DMA->crd_bit.hrdap;
break;
}
case EMAC_DMA_TX_BUFFER:
{
address = EMAC_DMA->ctbaddr_bit.htbap;
break;
}
case EMAC_DMA_RX_BUFFER:
{
address = EMAC_DMA->crbaddr_bit.hrbap;
break;
}
}
return address;
}
/**
* @brief reset all counter
* @param none
* @retval none
*/
void emac_mmc_counter_reset(void)
{
EMAC_MMC->ctrl_bit.rc = TRUE;
}
/**
* @brief counter stop counting from zero when it reaches maximum
* @param new_state: TRUE or FALSE.
* @retval none
*/
void emac_mmc_rollover_stop(confirm_state new_state)
{
EMAC_MMC->ctrl_bit.scr = new_state;
}
/**
* @brief enable reset on read
* @param new_state: TRUE or FALSE.
* @retval none
*/
void emac_mmc_reset_on_read_enable(confirm_state new_state)
{
EMAC_MMC->ctrl_bit.rr = new_state;
}
/**
* @brief freeze mmc counter
* @param new_state: TRUE or FALSE.
* @retval none
*/
void emac_mmc_counter_freeze(confirm_state new_state)
{
EMAC_MMC->ctrl_bit.fmc = new_state;
}
/**
* @brief interupt status of received frames
* @param flag: specifies the flag to check.
* this parameter can be one of the following values:
* - MMC_RX_CRC_ERROR
* - MMC_RX_ALIGN_ERROR
* - MMC_RX_GOOD_UNICAST
* @retval the new state of usart_flag (SET or RESET).
*/
flag_status emac_mmc_received_status_get(uint32_t flag)
{
if(EMAC_MMC->ri & flag)
{
return SET;
}
else
{
return RESET;
}
}
/**
* @brief interupt status of transmit frames
* @param transmit_type: transmit type.
* this parameter can be one of the following values:
* - MMC_TX_SINGLE_COL
* - MMC_TX_MULTIPLE_COL
* - MMC_TX_GOOD_FRAMES
* @retval the new state of usart_flag (SET or RESET).
*/
flag_status emac_mmc_transmit_status_get(uint32_t flag)
{
if(EMAC_MMC->ti & flag)
{
return SET;
}
else
{
return RESET;
}
}
/**
* @brief mask received mmc interrupt
* @param flag: specifies the flag to check.
* this parameter can be one of the following values:
* - MMC_RX_CRC_ERROR
* - MMC_RX_ALIGN_ERROR
* - MMC_RX_GOOD_UNICAST
* @param new_state: TRUE or FALSE.
* @retval none
*/
void emac_mmc_received_interrupt_mask_set(uint32_t flag, confirm_state new_state)
{
switch(flag)
{
case MMC_RX_CRC_ERROR:
{
EMAC_MMC->rim_bit.rcefcim = new_state;
break;
}
case MMC_RX_ALIGN_ERROR:
{
EMAC_MMC->rim_bit.raefacim = new_state;
break;
}
case MMC_RX_GOOD_UNICAST:
{
EMAC_MMC->rim_bit.rugfcim = new_state;
break;
}
}
}
/**
* @brief mask transmit mmc interrupt
* @param transmit_type: transmit type.
* this parameter can be one of the following values:
* - MMC_TX_SINGLE_COL
* - MMC_TX_MULTIPLE_COL
* - MMC_TX_GOOD_FRAMES
* @param new_state: TRUE or FALSE.
* @retval none
*/
void emac_mmc_transmit_interrupt_mask_set(uint32_t flag, confirm_state new_state)
{
switch(flag)
{
case MMC_TX_SINGLE_COL:
{
EMAC_MMC->tim_bit.tscgfcim = new_state;
break;
}
case MMC_TX_MULTIPLE_COL:
{
EMAC_MMC->tim_bit.tmcgfcim = new_state;
break;
}
case MMC_TX_GOOD_FRAMES:
{
EMAC_MMC->tim_bit.tgfcim = new_state;
break;
}
}
}
/**
* @brief get good frame numbers as single collision occurs.
* @param flag: specifies the flag to check.
* this parameter can be one of the following values:
* - MMC_TX_SINGLE_COL
* - MMC_TX_MULTIPLE_COL
* - MMC_TX_GOOD_FRAMES
* @retval good frames
*/
uint32_t emac_mmc_transmit_good_frames_get(uint32_t flag)
{
uint32_t good_frames = MMC_TX_GOOD_FRAMES;
switch(flag)
{
case MMC_TX_SINGLE_COL:
{
good_frames = EMAC_MMC->tfscc_bit.tgfscc;
break;
}
case MMC_TX_MULTIPLE_COL:
{
good_frames = EMAC_MMC->tfmscc_bit.tgfmscc;
break;
}
case MMC_TX_GOOD_FRAMES:
{
good_frames = EMAC_MMC->tfcnt_bit.tgfc;
break;
}
}
return good_frames;
}
/**
* @brief get good frame numbers as single collision occurs.
* @param flag: specifies the flag to check.
* this parameter can be one of the following values:
* - MMC_RX_CRC_ERROR
* - MMC_RX_ALIGN_ERROR
* - MMC_RX_GOOD_UNICAST
* @retval good frames
*/
uint32_t emac_mmc_received_error_frames_get(uint32_t flag)
{
uint32_t error_frames = MMC_RX_GOOD_UNICAST;
switch(flag)
{
case MMC_RX_CRC_ERROR:
{
error_frames = EMAC_MMC->rfcecnt_bit.rfcec;
break;
}
case MMC_RX_ALIGN_ERROR:
{
error_frames = EMAC_MMC->rfaecnt_bit.rfaec;
break;
}
case MMC_RX_GOOD_UNICAST:
{
error_frames = EMAC_MMC->rgufcnt_bit.rgufc;
break;
}
}
return error_frames;
}
/**
* @brief enable timestamp.
* @param new_state: TRUE or FALSE.
* @retval none
*/
void emac_ptp_timestamp_enable(confirm_state new_state)
{
EMAC_PTP->tsctrl_bit.te = new_state;
}
/**
* @brief enable timestamp fine update.
* @param new_state: TRUE or FALSE.
* @retval none
*/
void emac_ptp_timestamp_fine_update_enable(confirm_state new_state)
{
EMAC_PTP->tsctrl_bit.tfcu = new_state;
}
/**
* @brief initialize timestamp time system.
* @param new_state: TRUE or FALSE.
* @retval none
*/
void emac_ptp_timestamp_system_time_init(confirm_state new_state)
{
EMAC_PTP->tsctrl_bit.ti = new_state;
}
/**
* @brief update timestamp time system.
* @param new_state: TRUE or FALSE.
* @retval none
*/
void emac_ptp_timestamp_system_time_update(confirm_state new_state)
{
EMAC_PTP->tsctrl_bit.tu = new_state;
}
/**
* @brief enable timestamp interrupt trigger.
* @param new_state: TRUE or FALSE.
* @retval none
*/
void emac_ptp_interrupt_trigger_enable(confirm_state new_state)
{
EMAC_PTP->tsctrl_bit.tite = new_state;
}
/**
* @brief update timestamp addend register.
* @param new_state: TRUE or FALSE.
* @retval none
*/
void emac_ptp_addend_register_update(confirm_state new_state)
{
EMAC_PTP->tsctrl_bit.aru = new_state;
}
/**
* @brief enable timestamp snapshot for all received frames.
* @param new_state: TRUE or FALSE.
* @retval none
*/
void emac_ptp_snapshot_received_frames_enable(confirm_state new_state)
{
EMAC_PTP->tsctrl_bit.etaf = new_state;
}
/**
* @brief enable digital rollover.
* @param new_state: TRUE or FALSE.
* @retval none
*/
void emac_ptp_subsecond_rollover_enable(confirm_state new_state)
{
EMAC_PTP->tsctrl_bit.tdbrc = new_state;
}
/**
* @brief enable packet snooping for version 2.
* @param new_state: TRUE or FALSE.
* @retval none
*/
void emac_ptp_psv2_enable(confirm_state new_state)
{
EMAC_PTP->tsctrl_bit.eppv2f = new_state;
}
/**
* @brief enable snapshot over emac.
* @param new_state: TRUE or FALSE.
* @retval none
*/
void emac_ptp_snapshot_emac_frames_enable(confirm_state new_state)
{
EMAC_PTP->tsctrl_bit.eppef = new_state;
}
/**
* @brief enable snapshot for ipv6 frames.
* @param new_state: TRUE or FALSE.
* @retval none
*/
void emac_ptp_snapshot_ipv6_frames_enable(confirm_state new_state)
{
EMAC_PTP->tsctrl_bit.eppfsip6u = new_state;
}
/**
* @brief enable snapshot for ipv4 frames.
* @param new_state: TRUE or FALSE.
* @retval none
*/
void emac_ptp_snapshot_ipv4_frames_enable(confirm_state new_state)
{
EMAC_PTP->tsctrl_bit.eppfsip4u = new_state;
}
/**
* @brief enable snapshot for event message.
* @param new_state: TRUE or FALSE.
* @retval none
*/
void emac_ptp_snapshot_event_message_enable(confirm_state new_state)
{
EMAC_PTP->tsctrl_bit.etsfem = new_state;
}
/**
* @brief enable snapshot for message relevant to master
* @param new_state: TRUE or FALSE.
* @retval none
*/
void emac_ptp_snapshot_master_event_enable(confirm_state new_state)
{
EMAC_PTP->tsctrl_bit.esfmrtm = new_state;
}
/**
* @brief set clock node type
* @param node: select ptp packets for taking snapshot
* this parameter can be one of the following values:
* - EMAC_PTP_NORMAL_CLOCK
* - EMAC_PTP_BOUNDARY_CLOCK
* - EMAC_PTP_END_TO_END_CLOCK
* - EMAC_PTP_PEER_TO_PEER_CLOCK
* @retval none
*/
void emac_ptp_clock_node_set(emac_ptp_clock_node_type node)
{
EMAC_PTP->tsctrl_bit.sppfts = node;
}
/**
* @brief enable ptp frame filtering mac address
* @param new_state: TRUE or FALSE.
* @retval none
*/
void emac_ptp_mac_address_filter_enable(confirm_state new_state)
{
EMAC_PTP->tsctrl_bit.emafpff = new_state;
}
/**
* @brief set subsecond increment value
* @param value: add to subsecond value for every update
* @retval none
*/
void emac_ptp_subsecond_increment_set(uint8_t value)
{
EMAC_PTP->ssinc_bit.ssiv = value;
}
/**
* @brief get system time second
* @param none
* @retval system time second
*/
uint32_t emac_ptp_system_second_get(void)
{
uint32_t second = EMAC_PTP->tsh_bit.ts;
return second;
}
/**
* @brief get system time subsecond
* @param none
* @retval system time subsecond
*/
uint32_t emac_ptp_system_subsecond_get(void)
{
uint32_t subsecond = EMAC_PTP->tsl_bit.tss;
return subsecond;
}
/**
* @brief get system time sign
* @param none
* @retval TRUE or FALSE
*/
confirm_state emac_ptp_system_time_sign_get(void)
{
if(EMAC_PTP->tsl_bit.ast)
{
return TRUE;
}
else
{
return FALSE;
}
}
/**
* @brief set system time second
* @param second: system time second
* @retval none
*/
void emac_ptp_system_second_set(uint32_t second)
{
EMAC_PTP->tshud_bit.ts = second;
}
/**
* @brief set system time subsecond
* @param subsecond: system time subsecond
* @retval none
*/
void emac_ptp_system_subsecond_set(uint32_t subsecond)
{
EMAC_PTP->tslud_bit.tss = subsecond;
}
/**
* @brief set system time sign
* @param sign: TRUE or FALSE.
* @retval none
*/
void emac_ptp_system_time_sign_set(confirm_state sign)
{
if(sign)
{
EMAC_PTP->tslud_bit.ast = 1;
}
else
{
EMAC_PTP->tslud_bit.ast = 0;
}
}
/**
* @brief set time stamp addend
* @param value: to achieve time synchronization
* @retval none
*/
void emac_ptp_timestamp_addend_set(uint32_t value)
{
EMAC_PTP->tsad_bit.tar = value;
}
/**
* @brief set target time stamp high
* @param value: to set target time second
* @retval none
*/
void emac_ptp_target_second_set(uint32_t value)
{
EMAC_PTP->tth_bit.ttsr = value;
}
/**
* @brief set target time stamp low
* @param value: to set target time nanosecond
* @retval none
*/
void emac_ptp_target_nanosecond_set(uint32_t value)
{
EMAC_PTP->ttl_bit.ttlr = value;
}
/**
* @brief set target time stamp low
* @param status: type of status
* this parameter can be one of the following values:
* - EMAC_PTP_SECOND_OVERFLOW
* - EMAC_PTP_TARGET_TIME_REACH
* @retval TRUE or FALSE
*/
confirm_state emac_ptp_timestamp_status_get(emac_ptp_timestamp_status_type status)
{
switch(status)
{
case EMAC_PTP_SECOND_OVERFLOW:
{
if(EMAC_PTP->tssr_bit.tso)
{
return TRUE;
}
else
{
return FALSE;
}
}
case EMAC_PTP_TARGET_TIME_REACH:
{
if(EMAC_PTP->tssr_bit.tttr)
{
return TRUE;
}
else
{
return FALSE;
}
}
}
return FALSE;
}
/**
* @brief set pps frequency
* @param freq: pps frequency
* this parameter can be one of the following values:
* - EMAC_PTP_PPS_1HZ
* - EMAC_PTP_PPS_2HZ
* - EMAC_PTP_PPS_4HZ
* - EMAC_PTP_PPS_8HZ
* - EMAC_PTP_PPS_16HZ
* - EMAC_PTP_PPS_32HZ
* - EMAC_PTP_PPS_64HZ
* - EMAC_PTP_PPS_128HZ
* - EMAC_PTP_PPS_256HZ
* - EMAC_PTP_PPS_512HZ
* - EMAC_PTP_PPS_1024HZ
* - EMAC_PTP_PPS_2048HZ
* - EMAC_PTP_PPS_4096HZ
* - EMAC_PTP_PPS_8192HZ
* - EMAC_PTP_PPS_16384HZ
* - EMAC_PTP_PPS_32768HZ
* @retval none
*/
void emac_ptp_pps_frequency_set(emac_ptp_pps_control_type freq)
{
EMAC_PTP->ppscr_bit.pofc = freq;
}
/**
* @brief this is delay function base on system clock.
* @param delay: delay time
* @retval none
*/
static void emac_delay(uint32_t delay)
{
__IO uint32_t delay_time = delay * (system_core_clock / 8 / 1000);
do
{
__NOP();
}
while(delay_time --);
}
/**
* @brief check whether the specified emac dma flag is set or not.
* @param dma_flag: specifies the emac dma flag to check.
* this parameter can be one of emac dma flag status:
* - EMAC_DMA_TI_FLAG
* - EMAC_DMA_TPS_FLAG
* - EMAC_DMA_TBU_FLAG
* - EMAC_DMA_TJT_FLAG
* - EMAC_DMA_OVF_FLAG
* - EMAC_DMA_UNF_FLAG
* - EMAC_DMA_RI_FLAG
* - EMAC_DMA_RBU_FLAG
* - EMAC_DMA_RPS_FLAG
* - EMAC_DMA_RWT_FLAG
* - EMAC_DMA_ETI_FLAG
* - EMAC_DMA_FBEI_FLAG
* - EMAC_DMA_ERI_FLAG
* - EMAC_DMA_AIS_FLAG
* - EMAC_DMA_NIS_FLAG
* @retval the new state of dma_flag (SET or RESET).
*/
flag_status emac_dma_flag_get(uint32_t dma_flag)
{
flag_status status = RESET;
if(EMAC_DMA->sts & dma_flag)
status = SET;
/* return the new state (SET or RESET) */
return status;
}
/**
* @brief clear the emac dma flag.
* @param dma_flag: specifies the emac dma flags to clear.
* this parameter can be any combination of the following values:
* - EMAC_DMA_TI_FLAG
* - EMAC_DMA_TPS_FLAG
* - EMAC_DMA_TBU_FLAG
* - EMAC_DMA_TJT_FLAG
* - EMAC_DMA_OVF_FLAG
* - EMAC_DMA_UNF_FLAG
* - EMAC_DMA_RI_FLAG
* - EMAC_DMA_RBU_FLAG
* - EMAC_DMA_RPS_FLAG
* - EMAC_DMA_RWT_FLAG
* - EMAC_DMA_ETI_FLAG
* - EMAC_DMA_FBEI_FLAG
* - EMAC_DMA_ERI_FLAG
* - EMAC_DMA_AIS_FLAG
* - EMAC_DMA_NIS_FLAG
* @retval none
*/
void emac_dma_flag_clear(uint32_t dma_flag)
{
EMAC_DMA->sts = dma_flag;
}
/**
* @}
*/
#endif
/**
* @}
*/
#endif
/**
* @}
*/