The official Mbed 2 C/C++ SDK provides the software platform and libraries to build your applications.
Dependents: hello SerialTestv11 SerialTestv12 Sierpinski ... more
mbed 2
This is the mbed 2 library. If you'd like to learn about Mbed OS please see the mbed-os docs.
TARGET_ARM_CM3DS_MPS2/TOOLCHAIN_IAR/smsc9220_eth_drv.h
- Committer:
- AnnaBridge
- Date:
- 2019-02-20
- Revision:
- 172:65be27845400
File content as of revision 172:65be27845400:
/* * Copyright (c) 2016-2018 ARM Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * \file smsc9220_drv.h * \brief Generic driver for SMSC9220 Ethernet controller */ #ifndef __SMSC9220_ETH_H__ #define __SMSC9220_ETH_H__ #include "stdbool.h" #include "stdint.h" #ifdef __cplusplus extern "C" { #endif /** SMSC9220 device configuration structure */ struct smsc9220_eth_dev_cfg_t { const uint32_t base; /*!< SMSC9220 base address */ }; /** SMSC9220 device data structure */ struct smsc9220_eth_dev_data_t { uint32_t state; /*!< Indicates if the SMSC9220 driver is initialized and enabled */ void (*wait_ms) (int);/*!< function pointer to system's millisec delay function, will be used for delays */ uint32_t ongoing_packet_length;/*!< size in bytes of the packet is being sent */ uint32_t ongoing_packet_length_sent; /*!< size in bytes of the packet has been sent */ uint32_t current_rx_size_words; /*!< Data length in words, currently is being read */ }; /** SMSC9220 device structure */ struct smsc9220_eth_dev_t { const struct smsc9220_eth_dev_cfg_t* const cfg; /*!< configuration */ struct smsc9220_eth_dev_data_t* const data; /*!< data */ }; /** * \brief Error code definitions * */ enum smsc9220_error_t{ SMSC9220_ERROR_NONE = 0U, /*!< no error */ SMSC9220_ERROR_TIMEOUT = 1U, /*!< timeout */ SMSC9220_ERROR_BUSY = 2U, /*!< no error */ SMSC9220_ERROR_PARAM = 3U, /*!< invalid parameter */ SMSC9220_ERROR_INTERNAL = 4U /*!< internal error */ }; /** * \brief Interrupt source definitions * */ enum smsc9220_interrupt_source { SMSC9220_INTERRUPT_GPIO0 = 0U, SMSC9220_INTERRUPT_GPIO1 = 1U, SMSC9220_INTERRUPT_GPIO2 = 2U, SMSC9220_INTERRUPT_RX_STATUS_FIFO_LEVEL = 3U, SMSC9220_INTERRUPT_RX_STATUS_FIFO_FULL = 4U, /* 5 Reserved according to Datasheet */ SMSC9220_INTERRUPT_RX_DROPPED_FRAME = 6U, SMSC9220_INTERRUPT_TX_STATUS_FIFO_LEVEL = 7U, SMSC9220_INTERRUPT_TX_STATUS_FIFO_FULL = 8U, SMSC9220_INTERRUPT_TX_DATA_FIFO_AVAILABLE = 9U, SMSC9220_INTERRUPT_TX_DATA_FIFO_OVERRUN = 10U, /* 11, 12 Reserved according to Datasheet */ SMSC9220_INTERRUPT_TX_ERROR = 13U, SMSC9220_INTERRUPT_RX_ERROR = 14U, SMSC9220_INTERRUPT_RX_WATCHDOG_TIMEOUT = 15U, SMSC9220_INTERRUPT_TX_STATUS_OVERFLOW = 16U, SMSC9220_INTERRUPT_TX_POWER_MANAGEMENT = 17U, SMSC9220_INTERRUPT_PHY = 18U, SMSC9220_INTERRUPT_GP_TIMER = 19U, SMSC9220_INTERRUPT_RX_DMA = 20U, SMSC9220_INTERRUPT_TX_IOC = 21U, /* 22 Reserved according to Datasheet*/ SMSC9220_INTERRUPT_RX_DROPPED_FRAME_HALF = 23U, SMSC9220_INTERRUPT_RX_STOPPED = 24U, SMSC9220_INTERRUPT_TX_STOPPED = 25U, /* 26 - 30 Reserved according to Datasheet*/ SMSC9220_INTERRUPT_SW = 31U }; /** * \brief MAC register offset definitions * */ enum smsc9220_mac_reg_offsets_t{ SMSC9220_MAC_REG_OFFSET_CR = 0x1U, SMSC9220_MAC_REG_OFFSET_ADDRH = 0x2U, SMSC9220_MAC_REG_OFFSET_ADDRL = 0x3U, SMSC9220_MAC_REG_OFFSET_HASHH = 0x4U, SMSC9220_MAC_REG_OFFSET_HASHL = 0x5U, SMSC9220_MAC_REG_OFFSET_MII_ACC = 0x6U, SMSC9220_MAC_REG_OFFSET_MII_DATA = 0x7U, SMSC9220_MAC_REG_OFFSET_FLOW = 0x8U, SMSC9220_MAC_REG_OFFSET_VLAN1 = 0x9U, SMSC9220_MAC_REG_OFFSET_VLAN2 = 0xAU, SMSC9220_MAC_REG_OFFSET_WUFF = 0xBU, SMSC9220_MAC_REG_OFFSET_WUCSR = 0xCU, SMSC9220_MAC_REG_OFFSET_COE_CR = 0xDU }; /** * \brief PHY register offset definitions * */ enum phy_reg_offsets_t{ SMSC9220_PHY_REG_OFFSET_BCTRL = 0U, SMSC9220_PHY_REG_OFFSET_BSTATUS = 1U, SMSC9220_PHY_REG_OFFSET_ID1 = 2U, SMSC9220_PHY_REG_OFFSET_ID2 = 3U, SMSC9220_PHY_REG_OFFSET_ANEG_ADV = 4U, SMSC9220_PHY_REG_OFFSET_ANEG_LPA = 5U, SMSC9220_PHY_REG_OFFSET_ANEG_EXP = 6U, SMSC9220_PHY_REG_OFFSET_MCONTROL = 17U, SMSC9220_PHY_REG_OFFSET_MSTATUS = 18U, SMSC9220_PHY_REG_OFFSET_CSINDICATE = 27U, SMSC9220_PHY_REG_OFFSET_INTSRC = 29U, SMSC9220_PHY_REG_OFFSET_INTMASK = 30U, SMSC9220_PHY_REG_OFFSET_CS = 31U }; /* Bit definitions for PHY Basic Status Register */ #define PHY_REG_BSTATUS_EXTENDED_CAPABILITIES_INDEX 0U #define PHY_REG_BSTATUS_JABBER_DETECT_INDEX 1U #define PHY_REG_BSTATUS_LINK_STATUS_INDEX 2U #define PHY_REG_BSTATUS_AUTO_NEG_ABILITY_INDEX 3U #define PHY_REG_BSTATUS_REMOTE_FAULT_INDEX 4U #define PHY_REG_BSTATUS_AUTO_NEG_COMPLETE_INDEX 5U #define PHY_REG_BSTATUS_10BASE_T_HALF_DUPLEX_INDEX 11U #define PHY_REG_BSTATUS_10BASE_T_FULL_DUPLEX_INDEX 12U #define PHY_REG_BSTATUS_100BASE_TX_HALF_DUPLEX_INDEX 13U #define PHY_REG_BSTATUS_100BASE_TX_FULL_DUPLEX_INDEX 14U #define PHY_REG_BSTATUS_100BASE_T4_INDEX 15U /** * \brief FIFO Level Interrupt bit definitions * */ enum smsc9220_fifo_level_irq_pos_t{ SMSC9220_FIFO_LEVEL_IRQ_RX_STATUS_POS = 0U, SMSC9220_FIFO_LEVEL_IRQ_TX_STATUS_POS = 16U, SMSC9220_FIFO_LEVEL_IRQ_TX_DATA_POS = 24U }; /** * \brief FIFO Level Interrupt limits * */ #define SMSC9220_FIFO_LEVEL_IRQ_MASK 0xFFU #define SMSC9220_FIFO_LEVEL_IRQ_LEVEL_MIN 0U #define SMSC9220_FIFO_LEVEL_IRQ_LEVEL_MAX SMSC9220_FIFO_LEVEL_IRQ_MASK /** * \brief Initializes SMSC9220 Ethernet controller to a known default state: * - device ID is checked * - global interrupt is enabled, but all irq sources are disabled * - all capabilities are advertised * - 10Mbps able * - 10Mbps with full duplex * - 100Mbps Tx able * - 100Mbps with full duplex * - Symmetric Pause * - Asymmetric Pause * - Establish link enabled * - Rx enabled * - Tx enabled * Init should be called prior to any other process and * it's the caller's responsibility to follow proper call order. * * \param[in] dev Ethernet device structure \ref smsc9220_eth_dev_t * \param[in] wait_ms_function function pointer to a millisec delay function * for proper timing of some processes * * \return error code /ref smsc9220_error_t */ enum smsc9220_error_t smsc9220_init(const struct smsc9220_eth_dev_t* dev, void(* wait_ms_function)(int)); /** * \brief Read MAC register. * * \param[in] dev Ethernet device structure \ref smsc9220_eth_dev_t * \param[in] regoffset Register offset * \param[in, out] data Pointer to register will be read * * \return error code /ref smsc9220_error_t */ enum smsc9220_error_t smsc9220_mac_regread( const struct smsc9220_eth_dev_t* dev, enum smsc9220_mac_reg_offsets_t regoffset, uint32_t *data); /** * \brief Write MAC register. * * \param[in] dev Ethernet device structure \ref smsc9220_eth_dev_t * \param[in] regoffset Register offset * \param[in] data Register value to write * * \return error code /ref smsc9220_error_t */ enum smsc9220_error_t smsc9220_mac_regwrite( const struct smsc9220_eth_dev_t* dev, enum smsc9220_mac_reg_offsets_t regoffset, uint32_t data); /** * \brief Read PHY register. * * \param[in] dev Ethernet device structure \ref smsc9220_eth_dev_t * \param[in] regoffset Register offset * \param[out] data Register value is read * * \return error code /ref smsc9220_error_t */ enum smsc9220_error_t smsc9220_phy_regread( const struct smsc9220_eth_dev_t* dev, enum phy_reg_offsets_t, uint32_t *data); /** * \brief Write PHY register. * * \param[in] dev Ethernet device structure \ref smsc9220_eth_dev_t * \param[in] regoffset Register offset * \param[in] data Register value to write * * \return error code /ref smsc9220_error_t */ enum smsc9220_error_t smsc9220_phy_regwrite( const struct smsc9220_eth_dev_t* dev, enum phy_reg_offsets_t, uint32_t data); /** * \brief Read SMSC9220 ID. * * \param[in] dev Ethernet device structure \ref smsc9220_eth_dev_t * * \return ID number */ uint32_t smsc9220_read_id(const struct smsc9220_eth_dev_t* dev); /** * \brief Initiates a soft reset, returns failure or success. * * \param[in] dev Ethernet device structure \ref smsc9220_eth_dev_t * * \return error code /ref smsc9220_error_t */ enum smsc9220_error_t smsc9220_soft_reset( const struct smsc9220_eth_dev_t* dev); /** * \brief Set maximum transition unit by Tx fifo size. * Note: The MTU will be smaller by 512 bytes, * because the status uses this fixed space. * * \param[in] dev Ethernet device structure \ref smsc9220_eth_dev_t * \param[in] val Size of the fifo in kbytes * \ref HW_CFG_REG_TX_FIFO_SIZE_MIN * \ref HW_CFG_REG_TX_FIFO_SIZE_MAX */ void smsc9220_set_txfifo(const struct smsc9220_eth_dev_t* dev, uint32_t val); /** * \brief Set FIFO level interrupt for a given source * * \param[in] dev Ethernet device structure \ref smsc9220_eth_dev_t * \param[in] irq_level_pos Bit position of the FIFO to set * \ref smsc9220_fifo_level_irq_pos_t * \param[in] level Level of the FIFO, when the FIFO used space is greater * than this value, corresponding interrupt will be generated. * * \return error code /ref smsc9220_error_t */ enum smsc9220_error_t smsc9220_set_fifo_level_irq( const struct smsc9220_eth_dev_t* dev, enum smsc9220_fifo_level_irq_pos_t irq_level_pos, uint32_t level); /** * \brief Wait for EEPROM to be ready to use. * * \param[in] dev Ethernet device structure \ref smsc9220_eth_dev_t * * \return error code /ref smsc9220_error_t */ enum smsc9220_error_t smsc9220_wait_eeprom( const struct smsc9220_eth_dev_t* dev); /** * \brief Initialise irqs by clearing and disabling all interrupt sources * and enable interrupts. Since all interrupt sources are disabled, * interrupt won't be triggered, until interrupt sources won't be * enabled by \ref smsc9220_enable_interrupt * * \param[in] dev Ethernet device structure \ref smsc9220_eth_dev_t */ void smsc9220_init_irqs(const struct smsc9220_eth_dev_t* dev); /** * \brief Check PHY ID registers. * * \param[in] dev Ethernet device structure \ref smsc9220_eth_dev_t * * \return error code /ref smsc9220_error_t */ enum smsc9220_error_t smsc9220_check_phy(const struct smsc9220_eth_dev_t* dev); /** * \brief Reset PHY * * \param[in] dev Ethernet device structure \ref smsc9220_eth_dev_t * * \return error code /ref smsc9220_error_t */ enum smsc9220_error_t smsc9220_reset_phy(const struct smsc9220_eth_dev_t* dev); /** * \brief Advertise all speeds and pause capabilities * * \param[in] dev Ethernet device structure \ref smsc9220_eth_dev_t */ void smsc9220_advertise_cap(const struct smsc9220_eth_dev_t* dev); /** * \brief Enable transmission * * \param[in] dev Ethernet device structure \ref smsc9220_eth_dev_t */ void smsc9220_enable_xmit(const struct smsc9220_eth_dev_t* dev); /** * \brief Disable transmission * * \param[in] dev Ethernet device structure \ref smsc9220_eth_dev_t */ void smsc9220_disable_xmit(const struct smsc9220_eth_dev_t* dev); /** * \brief Enable MAC transmitter * * \param[in] dev Ethernet device structure \ref smsc9220_eth_dev_t */ void smsc9220_enable_mac_xmit(const struct smsc9220_eth_dev_t* dev); /** * \brief Disable MAC transmitter * * \param[in] dev Ethernet device structure \ref smsc9220_eth_dev_t */ void smsc9220_disable_mac_xmit(const struct smsc9220_eth_dev_t* dev); /** * \brief Enable receive * * \param[in] dev Ethernet device structure \ref smsc9220_eth_dev_t */ void smsc9220_enable_mac_recv(const struct smsc9220_eth_dev_t* dev); /** * \brief Disable receive * * \param[in] dev Ethernet device structure \ref smsc9220_eth_dev_t */ void smsc9220_disable_mac_recv(const struct smsc9220_eth_dev_t* dev); /** * \brief Enable the given interrupt source. * * \param[in] dev Ethernet device structure \ref smsc9220_eth_dev_t * \param[in] source Enum of the interrupt source. */ void smsc9220_enable_interrupt(const struct smsc9220_eth_dev_t* dev, enum smsc9220_interrupt_source source); /** * \brief Disable the given interrupt source. * * \param[in] dev Ethernet device structure \ref smsc9220_eth_dev_t * \param[in] source Enum of the interrupt source. */ void smsc9220_disable_interrupt(const struct smsc9220_eth_dev_t* dev, enum smsc9220_interrupt_source source); /** * \brief Disable all of the interrupt sources. * * \param[in] dev Ethernet device structure \ref smsc9220_eth_dev_t */ void smsc9220_disable_all_interrupts(const struct smsc9220_eth_dev_t* dev); /** * \brief Clear the given interrupt source. * * \param[in] dev Ethernet device structure \ref smsc9220_eth_dev_t * \param[in] source Enum of the interrupt source. */ void smsc9220_clear_interrupt(const struct smsc9220_eth_dev_t* dev, enum smsc9220_interrupt_source source); /** * \brief Clear all of the interrupt sources. * * \param[in] dev Ethernet device structure \ref smsc9220_eth_dev_t */ void smsc9220_clear_all_interrupts(const struct smsc9220_eth_dev_t* dev); /** * \brief Get the status of the given interrupt source. * * \param[in] dev Ethernet device structure \ref smsc9220_eth_dev_t * \param[in] source Enum of the interrupt source. * * \return non-zero if the given interrupt source is triggered, zero otherwise */ int smsc9220_get_interrupt(const struct smsc9220_eth_dev_t* dev, enum smsc9220_interrupt_source source); /** * \brief Establish link * * \param[in] dev Ethernet device structure \ref smsc9220_eth_dev_t */ void smsc9220_establish_link(const struct smsc9220_eth_dev_t* dev); /** * \brief Read MAC address from EEPROM. * * \param[in] dev Ethernet device structure \ref smsc9220_eth_dev_t * \param[in,out] mac array will include the read MAC address in * 6 bytes hexadecimal format. * It should be allocated by the caller to 6 bytes. * * \return error code /ref smsc9220_error_t */ enum smsc9220_error_t smsc9220_read_mac_address( const struct smsc9220_eth_dev_t* dev, char *mac); /** * \brief Check device ID. * * \return error code /ref smsc9220_error_t */ int smsc9220_check_id(const struct smsc9220_eth_dev_t* dev); /** * \brief Get the data size of the Tx buffer, aka Maximum Transition Unit * * \param[in] dev Ethernet device structure \ref smsc9220_eth_dev_t * * \return Fifo data size in bytes */ uint32_t smsc9220_get_tx_data_fifo_size(const struct smsc9220_eth_dev_t* dev); /** * \brief Send Ethernet packet from buffer chain. * The full packet length should be known in the beginning * of a new packet. * * \param[in] dev Ethernet device structure \ref smsc9220_eth_dev_t * \param[in] total_payload_length Length of the ethernet payload. * Should be equal to the sum of passed buffers within a packet. * \param[in] is_new_packet Should be set to true if the input buffer has to * be sent as the start of a new packet or as a full packet. * \param[in] data Pointer to the data should be sent. * \param[in] current_size Size of the data in bytes. * * \return error code /ref smsc9220_error_t */ enum smsc9220_error_t smsc9220_send_by_chunks( const struct smsc9220_eth_dev_t* dev, uint32_t total_payload_length, bool is_new_packet, const char *data, uint32_t current_size); /** * \brief Receive Ethernet packet from Rx FIFO to the passed buffer. * Stops reading at packet border. * If the passed buffer is larger than the current packet, * the whole packet will be read into the buffer. * If the current packet is larger than the passed buffer, * the buffer will be filled with data and the next call * will continue the read from that point. * * \param[in] dev Ethernet device structure \ref smsc9220_eth_dev_t * \param[in,out] data Pointer where the data will be read to. * The caller is responsible to allocate it. * \param[in] dlen Length of the allocated data in bytes. * * \return Remaining bytes left in the fifo of the current packet. */ uint32_t smsc9220_receive_by_chunks(const struct smsc9220_eth_dev_t* dev, char *data, uint32_t dlen); /** * \brief Get the used space of Rx fifo in bytes. * * \param[in] dev Ethernet device structure \ref smsc9220_eth_dev_t * * \return Data received and waiting for read in bytes */ uint32_t smsc9220_get_rxfifo_data_used_space(const struct smsc9220_eth_dev_t* dev); /** * \brief Get the size of next unread packet in Rx buffer, using the peak * register, which is not destructive so can be read asynchronously. * Warning: In case of heavy receiving load, it's possible this register * is not perfectly in sync. * * \param[in] dev Ethernet device structure \ref smsc9220_eth_dev_t * * \return Size in bytes of the next packet can be read from Rx fifo, according * to the peek register. */ uint32_t smsc9220_peek_next_packet_size(const struct smsc9220_eth_dev_t* dev); #ifdef __cplusplus } #endif #endif /* __SMSC9220_ETH_H__ */