From c14c1959b1186bc79dd223f0a744a8220874bc5a Mon Sep 17 00:00:00 2001 From: gdisirio Date: Mon, 5 Sep 2011 15:05:12 +0000 Subject: [PATCH] git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3290 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32/mac_lld.c | 260 +++++++++++++++++++++++++++++++ os/hal/platforms/STM32/mac_lld.h | 200 ++++++++++++++++++++++++ os/hal/templates/mac_lld.c | 53 ++++--- os/hal/templates/mac_lld.h | 73 +++++++-- 4 files changed, 549 insertions(+), 37 deletions(-) create mode 100644 os/hal/platforms/STM32/mac_lld.c create mode 100644 os/hal/platforms/STM32/mac_lld.h diff --git a/os/hal/platforms/STM32/mac_lld.c b/os/hal/platforms/STM32/mac_lld.c new file mode 100644 index 000000000..37ca9e106 --- /dev/null +++ b/os/hal/platforms/STM32/mac_lld.c @@ -0,0 +1,260 @@ +/* + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, + 2011 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + * @file STM32/mac_lld.c + * @brief STM32 low level MAC driver code. + * + * @addtogroup MAC + * @{ + */ + +#include "ch.h" +#include "hal.h" +#include "mii.h" +# +#if HAL_USE_MAC || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + +#define BUFFER_SLICE ((((MAC_BUFFERS_SIZE - 1) | 3) + 1) / 4) + +/*===========================================================================*/ +/* Driver exported variables. */ +/*===========================================================================*/ + +/** + * @brief Ethernet driver 1. + */ +MACDriver ETH1; + +/*===========================================================================*/ +/* Driver local variables. */ +/*===========================================================================*/ + +static stm32_eth_rx_descriptor_t *rxptr; +static stm32_eth_tx_descriptor_t *txptr; + +static stm32_eth_rx_descriptor_t rd[MAC_RECEIVE_BUFFERS]; +static stm32_eth_tx_descriptor_t td[MAC_TRANSMIT_BUFFERS]; + +static uint32_t rb[MAC_RECEIVE_BUFFERS * BUFFER_SLICE]; +static uint32_t tb[MAC_TRANSMIT_BUFFERS * BUFFER_SLICE]; + +/*===========================================================================*/ +/* Driver local functions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver interrupt handlers. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver exported functions. */ +/*===========================================================================*/ + +/** + * @brief Low level MAC initialization. + * + * @notapi + */ +void mac_lld_init(void) { + unsigned i; + + macObjectInit(Ð1); + + /* Descriptor tables are initialized in linked mode, note that the first + word is not initialized here but in mac_lld_start().*/ + for (i = 0; i < MAC_RECEIVE_BUFFERS; i++) { + rd[i].rdes1 = RDES1_RCH | MAC_BUFFERS_SIZE; + rd[i].rdes2 = (uint32_t)&rb[i * BUFFER_SLICE]; + rd[i].rdes3 = (uint32_t)&rb[((i + 1) % MAC_RECEIVE_BUFFERS) * + BUFFER_SLICE]; + } + for (i = 0; i < MAC_TRANSMIT_BUFFERS; i++) { + td[i].tdes1 = 0; + td[i].tdes2 = (uint32_t)&tb[i * BUFFER_SLICE]; + td[i].tdes3 = (uint32_t)&tb[((i + 1) % MAC_TRANSMIT_BUFFERS) * + BUFFER_SLICE]; + } +} + +/** + * @brief Configures and activates the MAC peripheral. + * + * @param[in] macp pointer to the @p MACDriver object + * + * @notapi + */ +void mac_lld_start(MACDriver *macp) { + unsigned i; + + /* Resets the state of all descriptors.*/ + for (i = 0; i < MAC_RECEIVE_BUFFERS; i++) + rd[i].rdes0 = RDES0_OWN; + rxptr = (stm32_eth_rx_descriptor_t *)rd; + for (i = 0; i < MAC_TRANSMIT_BUFFERS; i++) + td[i].tdes0 = TDES0_TCH; + txptr = (stm32_eth_tx_descriptor_t *)td; + + /* Soft reset of the MAC core and wait until the reset is complete.*/ + ETH->DMABMR |= ETH_DMABMR_SR; + while (ETH->DMABMR & ETH_DMABMR_SR) + ; + + /* Descriptor chains pointers.*/ + ETH->DMARDLAR = (uint32_t)rd; + ETH->DMATDLAR = (uint32_t)rd; + + /* Clear DMA status.*/ +} + +/** + * @brief Deactivates the MAC peripheral. + * + * @param[in] macp pointer to the @p MACDriver object + * + * @notapi + */ +void mac_lld_stop(MACDriver *macp) { + +} + +/** + * @brief Returns a transmission descriptor. + * @details One of the available transmission descriptors is locked and + * returned. + * + * @param[in] macp pointer to the @p MACDriver object + * @param[out] tdp pointer to a @p MACTransmitDescriptor structure + * @return The operation status. + * @retval RDY_OK the descriptor has been obtained. + * @retval RDY_TIMEOUT descriptor not available. + * + * @notapi + */ +msg_t max_lld_get_transmit_descriptor(MACDriver *macp, + MACTransmitDescriptor *tdp) { + + return RDY_OK; +} + +/** + * @brief Writes to a transmit descriptor's stream. + * + * @param[in] tdp pointer to a @p MACTransmitDescriptor structure + * @param[in] buf pointer to the buffer cointaining the data to be + * written + * @param[in] size number of bytes to be written + * @return The number of bytes written into the descriptor's + * stream, this value can be less than the amount + * specified in the parameter @p size if the maximum + * frame size is reached. + * + * @notapi + */ +size_t mac_lld_write_transmit_descriptor(MACTransmitDescriptor *tdp, + uint8_t *buf, + size_t size) { + + return 0; +} + +/** + * @brief Releases a transmit descriptor and starts the transmission of the + * enqueued data as a single frame. + * + * @param[in] tdp the pointer to the @p MACTransmitDescriptor structure + * + * @notapi + */ +void mac_lld_release_transmit_descriptor(MACTransmitDescriptor *tdp) { + +} + +/** + * @brief Returns a receive descriptor. + * + * @param[in] macp pointer to the @p MACDriver object + * @param[out] rdp pointer to a @p MACReceiveDescriptor structure + * @return The operation status. + * @retval RDY_OK the descriptor has been obtained. + * @retval RDY_TIMEOUT descriptor not available. + * + * @notapi + */ +msg_t max_lld_get_receive_descriptor(MACDriver *macp, + MACReceiveDescriptor *rdp) { + + return RDY_TIMEOUT; +} + +/** + * @brief Reads from a receive descriptor's stream. + * + * @param[in] rdp pointer to a @p MACReceiveDescriptor structure + * @param[in] buf pointer to the buffer that will receive the read data + * @param[in] size number of bytes to be read + * @return The number of bytes read from the descriptor's + * stream, this value can be less than the amount + * specified in the parameter @p size if there are + * no more bytes to read. + * + * @notapi + */ +size_t mac_lld_read_receive_descriptor(MACReceiveDescriptor *rdp, + uint8_t *buf, + size_t size) { + + return 0; +} + +/** + * @brief Releases a receive descriptor. + * @details The descriptor and its buffer are made available for more incoming + * frames. + * + * @param[in] rdp the pointer to the @p MACReceiveDescriptor structure + * + * @notapi + */ +void mac_lld_release_receive_descriptor(MACReceiveDescriptor *rdp) { + +} + +/** + * @brief Updates and returns the link status. + * + * @param[in] macp pointer to the @p MACDriver object + * @return The link status. + * @retval TRUE if the link is active. + * @retval FALSE if the link is down. + * + * @notapi + */ +bool_t mac_lld_poll_link_status(MACDriver *macp) { + +} + +#endif /* HAL_USE_MAC */ + +/** @} */ diff --git a/os/hal/platforms/STM32/mac_lld.h b/os/hal/platforms/STM32/mac_lld.h new file mode 100644 index 000000000..8647bd296 --- /dev/null +++ b/os/hal/platforms/STM32/mac_lld.h @@ -0,0 +1,200 @@ +/* + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, + 2011 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + * @file STM32/mac_lld.h + * @brief STM32 low level MAC driver header. + * + * @addtogroup MAC + * @{ + */ + +#ifndef _MAC_LLD_H_ +#define _MAC_LLD_H_ + +#if HAL_USE_MAC || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Driver constants. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver pre-compile time settings. */ +/*===========================================================================*/ + +/** + * @brief Number of available transmit buffers. + */ +#if !defined(MAC_TRANSMIT_BUFFERS) || defined(__DOXYGEN__) +#define MAC_TRANSMIT_BUFFERS 2 +#endif + +/** + * @brief Number of available receive buffers. + */ +#if !defined(MAC_RECEIVE_BUFFERS) || defined(__DOXYGEN__) +#define MAC_RECEIVE_BUFFERS 2 +#endif + +/** + * @brief Maximum supported frame size. + */ +#if !defined(MAC_BUFFERS_SIZE) || defined(__DOXYGEN__) +#define MAC_BUFFERS_SIZE 1518 +#endif + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver data structures and types. */ +/*===========================================================================*/ + +/** + * @brief Type of an STM32 Ethernet receive descriptor. + */ +typedef struct { + volatile uint32_t rdes0; + volatile uint32_t rdes1; + volatile uint32_t rdes2; + volatile uint32_t rdes3; +} stm32_eth_rx_descriptor_t; + +/** + * @brief Type of an STM32 Ethernet transmit descriptor. + */ +typedef struct { + volatile uint32_t tdes0; + volatile uint32_t tdes1; + volatile uint32_t tdes2; + volatile uint32_t tdes3; +} stm32_eth_tx_descriptor_t; + +/** + * @brief Driver configuration structure. + */ +typedef struct { + /** + * @brief MAC address. + */ + uint8_t *mac_address; + /* End of the mandatory fields.*/ +} MACConfig; + +/** + * @brief Structure representing a MAC driver. + */ +struct MACDriver { + /** + * @brief Driver state. + */ + macstate_t state; + /** + * @brief Current configuration data. + */ + const MACConfig *config; + /** + * @brief Transmit semaphore. + */ + Semaphore tdsem; + /** + * @brief Receive semaphore. + */ + Semaphore rdsem; +#if MAC_USE_EVENTS || defined(__DOXYGEN__) + /** + * @brief Receive event. + */ + EventSource rdevent; +#endif + /* End of the mandatory fields.*/ +}; + +/** + * @brief Structure representing a transmit descriptor. + */ +typedef struct { + /** + * @brief Current write offset. + */ + size_t offset; + /** + * @brief Available space size. + */ + size_t size; + /* End of the mandatory fields.*/ +} MACTransmitDescriptor; + +/** + * @brief Structure representing a receive descriptor. + */ +typedef struct { + /** + * @brief Current read offset. + */ + size_t offset; + /** + * @brief Available data size. + */ + size_t size; + /* End of the mandatory fields.*/ +} MACReceiveDescriptor; + +/*===========================================================================*/ +/* Driver macros. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +#if !defined(__DOXYGEN__) +extern MACDriver ETH1; +#endif + +#ifdef __cplusplus +extern "C" { +#endif + void mac_lld_init(void); + void mac_lld_start(MACDriver *macp); + void mac_lld_stop(MACDriver *macp); + msg_t max_lld_get_transmit_descriptor(MACDriver *macp, + MACTransmitDescriptor *tdp); + size_t mac_lld_write_transmit_descriptor(MACTransmitDescriptor *tdp, + uint8_t *buf, + size_t size); + void mac_lld_release_transmit_descriptor(MACTransmitDescriptor *tdp); + msg_t max_lld_get_receive_descriptor(MACDriver *macp, + MACReceiveDescriptor *rdp); + size_t mac_lld_read_receive_descriptor(MACReceiveDescriptor *rdp, + uint8_t *buf, + size_t size); + void mac_lld_release_receive_descriptor(MACReceiveDescriptor *rdp); + bool_t mac_lld_poll_link_status(MACDriver *macp); +#ifdef __cplusplus +} +#endif + +#endif /* HAL_USE_MAC */ + +#endif /* _MAC_LLD_H_ */ + +/** @} */ diff --git a/os/hal/templates/mac_lld.c b/os/hal/templates/mac_lld.c index 62b8765d0..ecd7f82bd 100644 --- a/os/hal/templates/mac_lld.c +++ b/os/hal/templates/mac_lld.c @@ -39,6 +39,11 @@ /* Driver exported variables. */ /*===========================================================================*/ +/** + * @brief Ethernet driver 1. + */ +MACDriver ETH1; + /*===========================================================================*/ /* Driver local variables. */ /*===========================================================================*/ @@ -65,16 +70,24 @@ void mac_lld_init(void) { } /** - * @brief Low level MAC address setup. + * @brief Configures and activates the MAC peripheral. * * @param[in] macp pointer to the @p MACDriver object - * @param[in] p pointer to a six bytes buffer containing the MAC - * address. If this parameter is set to @p NULL then - * a system default MAC is used. * * @notapi */ -void mac_lld_set_address(MACDriver *macp, const uint8_t *p) { +void mac_lld_start(MACDriver *macp) { + +} + +/** + * @brief Deactivates the MAC peripheral. + * + * @param[in] macp pointer to the @p MACDriver object + * + * @notapi + */ +void mac_lld_stop(MACDriver *macp) { } @@ -86,7 +99,7 @@ void mac_lld_set_address(MACDriver *macp, const uint8_t *p) { * @param[in] macp pointer to the @p MACDriver object * @param[out] tdp pointer to a @p MACTransmitDescriptor structure * @return The operation status. - * @retval RDY_OK a descriptor was obtained. + * @retval RDY_OK the descriptor has been obtained. * @retval RDY_TIMEOUT descriptor not available. * * @notapi @@ -101,7 +114,7 @@ msg_t max_lld_get_transmit_descriptor(MACDriver *macp, * @brief Writes to a transmit descriptor's stream. * * @param[in] tdp pointer to a @p MACTransmitDescriptor structure - * @param[in] buf pointer to the buffer containing the data to be + * @param[in] buf pointer to the buffer cointaining the data to be * written * @param[in] size number of bytes to be written * @return The number of bytes written into the descriptor's @@ -122,7 +135,7 @@ size_t mac_lld_write_transmit_descriptor(MACTransmitDescriptor *tdp, * @brief Releases a transmit descriptor and starts the transmission of the * enqueued data as a single frame. * - * @param[in] tdp pointer to a @p MACTransmitDescriptor structure + * @param[in] tdp the pointer to the @p MACTransmitDescriptor structure * * @notapi */ @@ -133,10 +146,10 @@ void mac_lld_release_transmit_descriptor(MACTransmitDescriptor *tdp) { /** * @brief Returns a receive descriptor. * - * @param[in] macp pointer to a @p MACDriver object + * @param[in] macp pointer to the @p MACDriver object * @param[out] rdp pointer to a @p MACReceiveDescriptor structure * @return The operation status. - * @retval RDY_OK a descriptor was obtained. + * @retval RDY_OK the descriptor has been obtained. * @retval RDY_TIMEOUT descriptor not available. * * @notapi @@ -144,18 +157,19 @@ void mac_lld_release_transmit_descriptor(MACTransmitDescriptor *tdp) { msg_t max_lld_get_receive_descriptor(MACDriver *macp, MACReceiveDescriptor *rdp) { - return RDY_OK; + return RDY_TIMEOUT; } /** * @brief Reads from a receive descriptor's stream. * - * @param[in] rdp pointer to a @p MACReceiveDescriptor structure - * @param[in] buf pointer to a buffer that will receive the read data - * @param[in] size number of bytes to be read - * @return The number of bytes read from the descriptor's stream, - * this value can be less than the amount specified in - * the parameter @p size if there are no more bytes to read. + * @param[in] rdp pointer to a @p MACReceiveDescriptor structure + * @param[in] buf pointer to the buffer that will receive the read data + * @param[in] size number of bytes to be read + * @return The number of bytes read from the descriptor's + * stream, this value can be less than the amount + * specified in the parameter @p size if there are + * no more bytes to read. * * @notapi */ @@ -171,7 +185,7 @@ size_t mac_lld_read_receive_descriptor(MACReceiveDescriptor *rdp, * @details The descriptor and its buffer are made available for more incoming * frames. * - * @param[in] rdp pointer to a @p MACReceiveDescriptor structure + * @param[in] rdp the pointer to the @p MACReceiveDescriptor structure * * @notapi */ @@ -182,7 +196,7 @@ void mac_lld_release_receive_descriptor(MACReceiveDescriptor *rdp) { /** * @brief Updates and returns the link status. * - * @param[in] macp pointer to a @p MACDriver object + * @param[in] macp pointer to the @p MACDriver object * @return The link status. * @retval TRUE if the link is active. * @retval FALSE if the link is down. @@ -191,7 +205,6 @@ void mac_lld_release_receive_descriptor(MACReceiveDescriptor *rdp) { */ bool_t mac_lld_poll_link_status(MACDriver *macp) { - return FALSE; } #endif /* HAL_USE_MAC */ diff --git a/os/hal/templates/mac_lld.h b/os/hal/templates/mac_lld.h index e103128a9..765ac247e 100644 --- a/os/hal/templates/mac_lld.h +++ b/os/hal/templates/mac_lld.h @@ -48,38 +48,72 @@ /*===========================================================================*/ /** - * @brief Structure representing a MAC driver. - * @note Implementations may extend this structure to contain more, - * architecture dependent, fields. + * @brief Driver configuration structure. */ typedef struct { - Semaphore tdsem; /**< Transmit semaphore. */ - Semaphore rdsem; /**< Receive semaphore. */ -#if CH_USE_EVENTS - EventSource rdevent; /**< Receive event source. */ + /** + * @brief MAC address. + */ + uint8_t *mac_address; + /* End of the mandatory fields.*/ +} MACConfig; + +/** + * @brief Structure representing a MAC driver. + */ +struct MACDriver { + /** + * @brief Driver state. + */ + macstate_t state; + /** + * @brief Current configuration data. + */ + const MACConfig *config; + /** + * @brief Transmit semaphore. + */ + Semaphore tdsem; + /** + * @brief Receive semaphore. + */ + Semaphore rdsem; +#if MAC_USE_EVENTS || defined(__DOXYGEN__) + /** + * @brief Receive event. + */ + EventSource rdevent; #endif /* End of the mandatory fields.*/ -} MACDriver; +}; /** * @brief Structure representing a transmit descriptor. - * @note Implementations may extend this structure to contain more, - * architecture dependent, fields. */ typedef struct { - size_t offset; /**< Current write offset. */ - size_t size; /**< Available space size. */ + /** + * @brief Current write offset. + */ + size_t offset; + /** + * @brief Available space size. + */ + size_t size; /* End of the mandatory fields.*/ } MACTransmitDescriptor; /** * @brief Structure representing a receive descriptor. - * @note Implementations may extend this structure to contain more, - * architecture dependent, fields. */ typedef struct { - size_t offset; /**< Current read offset. */ - size_t size; /**< Available data size. */ + /** + * @brief Current read offset. + */ + size_t offset; + /** + * @brief Available data size. + */ + size_t size; /* End of the mandatory fields.*/ } MACReceiveDescriptor; @@ -91,11 +125,16 @@ typedef struct { /* External declarations. */ /*===========================================================================*/ +#if !defined(__DOXYGEN__) +extern MACDriver ETH1; +#endif + #ifdef __cplusplus extern "C" { #endif void mac_lld_init(void); - void mac_lld_set_address(MACDriver *macp, const uint8_t *p); + void mac_lld_start(MACDriver *macp); + void mac_lld_stop(MACDriver *macp); msg_t max_lld_get_transmit_descriptor(MACDriver *macp, MACTransmitDescriptor *tdp); size_t mac_lld_write_transmit_descriptor(MACTransmitDescriptor *tdp,