From 792d85bcb5774e63100abef0125d5325312f916a Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sat, 3 Sep 2011 12:35:41 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3287 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/include/mac.h | 36 ++++++++++++++++- os/hal/platforms/AT91SAM7/mac_lld.c | 74 ++++++++++++++++++++++------------ os/hal/platforms/AT91SAM7/mac_lld.h | 80 +++++++++++++++++++++++++++++-------- os/hal/src/mac.c | 63 ++++++++++++++++++++++++----- 4 files changed, 198 insertions(+), 55 deletions(-) (limited to 'os/hal') diff --git a/os/hal/include/mac.h b/os/hal/include/mac.h index 37d6bbe9b..c716796f8 100644 --- a/os/hal/include/mac.h +++ b/os/hal/include/mac.h @@ -38,18 +38,48 @@ /* Driver pre-compile time settings. */ /*===========================================================================*/ +/** + * @name MAC configuration options + * @{ + */ +/** + * @brief Enables an event sources for incoming packets. + */ +#if !defined(MAC_USE_EVENTS) || defined(__DOXYGEN__) +#define MAC_USE_EVENTS TRUE +#endif +/** @} */ + /*===========================================================================*/ /* Derived constants and error checks. */ /*===========================================================================*/ #if !CH_USE_SEMAPHORES || !CH_USE_EVENTS -#error "the MAC driver requires CH_USE_SEMAPHORES and CH_USE_EVENTS" +#error "the MAC driver requires CH_USE_SEMAPHORES" +#endif + +#if MAC_USE_EVENTS && !CH_USE_EVENTS +#error "the MAC driver requires CH_USE_EVENTS" #endif /*===========================================================================*/ /* Driver data structures and types. */ /*===========================================================================*/ +/** + * @brief Driver state machine possible states. + */ +typedef enum { + MAC_UNINIT = 0, /**< Not initialized. */ + MAC_STOP = 1, /**< Stopped. */ + MAC_ACTIVE = 2, /**< Active. */ +} macstate_t; + +/** + * @brief Type of a structure representing a MAC driver. + */ +typedef struct MACDriver MACDriver; + #include "mac_lld.h" /*===========================================================================*/ @@ -68,7 +98,7 @@ * * @api */ -#if CH_USE_EVENTS || defined(__DOXYGEN__) +#if MAC_USE_EVENTS || defined(__DOXYGEN__) #define macGetReceiveEventSource(macp) (&(macp)->rdevent) #endif @@ -113,6 +143,8 @@ extern "C" { #endif void macInit(void); void macObjectInit(MACDriver *macp); + void macStart(MACDriver *macp, const MACConfig *config); + void macStop(MACDriver *macp); void macSetAddress(MACDriver *macp, const uint8_t *p); msg_t macWaitTransmitDescriptor(MACDriver *macp, MACTransmitDescriptor *tdp, diff --git a/os/hal/platforms/AT91SAM7/mac_lld.c b/os/hal/platforms/AT91SAM7/mac_lld.c index 43055b94d..fc610fcc7 100644 --- a/os/hal/platforms/AT91SAM7/mac_lld.c +++ b/os/hal/platforms/AT91SAM7/mac_lld.c @@ -64,7 +64,6 @@ MACDriver ETH1; /*===========================================================================*/ #ifndef __DOXYGEN__ -static bool_t link_up; static uint8_t default_mac[] = {0xAA, 0x55, 0x13, 0x37, 0x01, 0x10}; @@ -102,7 +101,7 @@ static void serve_interrupt(void) { if (rsr & AT91C_EMAC_REC) { chSysLockFromIsr(); chSemResetI(Ð1.rdsem, 0); -#if CH_USE_EVENTS +#if MAC_USE_EVENTS chEvtBroadcastI(Ð1.rdevent); #endif chSysUnlockFromIsr(); @@ -135,6 +134,19 @@ static void cleanup(EMACDescriptor *from) { } } +/** + * @brief MAC address setup. + * + * @param[in] p pointer to a six bytes buffer containing the MAC + * address + */ +static void set_address(const uint8_t *p) { + + AT91C_BASE_EMAC->EMAC_SA1L = (AT91_REG)((p[3] << 24) | (p[2] << 16) | + (p[1] << 8) | p[0]); + AT91C_BASE_EMAC->EMAC_SA1H = (AT91_REG)((p[5] << 8) | p[4]); +} + /*===========================================================================*/ /* Driver interrupt handlers. */ /*===========================================================================*/ @@ -163,11 +175,34 @@ CH_IRQ_HANDLER(irq_handler) { * @notapi */ void mac_lld_init(void) { - unsigned i; miiInit(); macObjectInit(Ð1); + /* + * Associated PHY initialization. + */ + miiReset(Ð1); + + /* + * EMAC pins setup. Note, PB18 is not included because it is + * used as #PD control and not as EF100. + */ + AT91C_BASE_PIOB->PIO_ASR = EMAC_PIN_MASK; + AT91C_BASE_PIOB->PIO_PDR = EMAC_PIN_MASK; + AT91C_BASE_PIOB->PIO_PPUDR = EMAC_PIN_MASK; +} + +/** + * @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; + /* * Buffers initialization. */ @@ -185,18 +220,9 @@ void mac_lld_init(void) { txptr = td; /* - * Associated PHY initialization. - */ - miiReset(Ð1); - - /* - * EMAC pins setup and clock enable. Note, PB18 is not included because it is - * used as #PD control and not as EF100. + * EMAC clock enable. */ AT91C_BASE_PMC->PMC_PCER = 1 << AT91C_ID_EMAC; - AT91C_BASE_PIOB->PIO_ASR = EMAC_PIN_MASK; - AT91C_BASE_PIOB->PIO_PDR = EMAC_PIN_MASK; - AT91C_BASE_PIOB->PIO_PPUDR = EMAC_PIN_MASK; /* * EMAC Initial setup. @@ -213,7 +239,10 @@ void mac_lld_init(void) { AT91C_BASE_EMAC->EMAC_NCR |= AT91C_EMAC_TE | AT91C_EMAC_RE | AT91C_EMAC_CLRSTAT;/* Initial NCR settings.*/ - mac_lld_set_address(Ð1, default_mac); + if (macp->config->mac_address == NULL) + set_address(default_mac); + else + set_address(macp->config->mac_address); /* * PHY device identification. @@ -235,22 +264,15 @@ void mac_lld_init(void) { } /** - * @brief Low level MAC address setup. + * @brief Deactivates 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. The MAC address must - * be aligned with the most significant byte first. * * @notapi */ -void mac_lld_set_address(MACDriver *macp, const uint8_t *p) { +void mac_lld_stop(MACDriver *macp) { (void)macp; - AT91C_BASE_EMAC->EMAC_SA1L = (AT91_REG)((p[3] << 24) | (p[2] << 16) | - (p[1] << 8) | p[0]); - AT91C_BASE_EMAC->EMAC_SA1H = (AT91_REG)((p[5] << 8) | p[4]); } /** @@ -272,7 +294,7 @@ msg_t max_lld_get_transmit_descriptor(MACDriver *macp, (void)macp; - if (!link_up) + if (!macp->link_up) return RDY_TIMEOUT; chSysLock(); @@ -505,7 +527,7 @@ bool_t mac_lld_poll_link_status(MACDriver *macp) { bmsr = miiGet(macp, MII_BMSR); if (!(bmsr & BMSR_LSTATUS)) { AT91C_BASE_EMAC->EMAC_NCR &= ~AT91C_EMAC_MPE; - return link_up = FALSE; + return macp->link_up = FALSE; } ncfgr = AT91C_BASE_EMAC->EMAC_NCFGR & ~(AT91C_EMAC_SPD | AT91C_EMAC_FD); @@ -525,7 +547,7 @@ bool_t mac_lld_poll_link_status(MACDriver *macp) { } AT91C_BASE_EMAC->EMAC_NCFGR = ncfgr; AT91C_BASE_EMAC->EMAC_NCR &= ~AT91C_EMAC_MPE; - return link_up = TRUE; + return macp->link_up = TRUE; } #endif /* HAL_USE_MAC */ diff --git a/os/hal/platforms/AT91SAM7/mac_lld.h b/os/hal/platforms/AT91SAM7/mac_lld.h index 9f30e0426..97a8ba2ae 100644 --- a/os/hal/platforms/AT91SAM7/mac_lld.h +++ b/os/hal/platforms/AT91SAM7/mac_lld.h @@ -128,38 +128,85 @@ typedef struct { } EMACDescriptor; /** - * @brief Structure representing a MAC driver. + * @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 Link status flag. + */ + bool_t link_up; +}; /** * @brief Structure representing a transmit descriptor. */ 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.*/ - EMACDescriptor *physdesc; /**< Pointer to the physical - descriptor. */ + /** + * @brief Pointer to the physical descriptor. + */ + EMACDescriptor *physdesc; } MACTransmitDescriptor; /** * @brief Structure representing a receive descriptor. */ 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.*/ - EMACDescriptor *physdesc; /**< Pointer to the first - descriptor of the buffers - chain. */ + /** + * @brief Pointer to the first descriptor of the buffers chain. + */ + EMACDescriptor *physdesc; } MACReceiveDescriptor; /*===========================================================================*/ @@ -178,7 +225,8 @@ extern MACDriver ETH1; 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, diff --git a/os/hal/src/mac.c b/os/hal/src/mac.c index 0f1c47576..edd15d087 100644 --- a/os/hal/src/mac.c +++ b/os/hal/src/mac.c @@ -21,8 +21,6 @@ /** * @file mac.c * @brief MAC Driver code. - * @note This function is implicitly invoked by @p halInit(), there is - * no need to explicitly initialize the driver. * * @addtogroup MAC * @{ @@ -59,6 +57,8 @@ /** * @brief MAC Driver initialization. + * @note This function is implicitly invoked by @p halInit(), there is + * no need to explicitly initialize the driver. * * @init */ @@ -76,28 +76,53 @@ void macInit(void) { */ void macObjectInit(MACDriver *macp) { + macp->state = MAC_STOP; + macp->config = NULL; chSemInit(&macp->tdsem, 0); chSemInit(&macp->rdsem, 0); -#if CH_USE_EVENTS +#if MAC_USE_EVENTS chEvtInit(&macp->rdevent); #endif } /** - * @brief MAC address setup. - * @pre This function must be invoked with the driver in the stopped - * state. If invoked on an active interface then it is ignored. + * @brief Configures and activates the MAC peripheral. + * + * @param[in] macp pointer to the @p MACDriver object + * @param[in] config pointer to the @p MACConfig object + * + * @api + */ +void macStart(MACDriver *macp, const MACConfig *config) { + + chDbgCheck((macp != NULL) && (config != NULL), "macStart"); + + chSysLock(); + chDbgAssert(macp->state == MAC_STOP, + "macStart(), #1", "invalid state"); + macp->config = config; + mac_lld_start(macp); + macp->state = MAC_ACTIVE; + chSysUnlock(); +} + +/** + * @brief Deactivates 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 MAC - * a system default is used. * * @api */ -void macSetAddress(MACDriver *macp, const uint8_t *p) { +void macStop(MACDriver *macp) { + + chDbgCheck(macp != NULL, "macStop"); - mac_lld_set_address(macp, p); + chSysLock(); + chDbgAssert((macp->state == MAC_STOP) || (macp->state == MAC_ACTIVE), + "macStop(), #1", "invalid state"); + mac_lld_stop(macp); + macp->state = MAC_STOP; + chSysUnlock(); } /** @@ -124,6 +149,10 @@ msg_t macWaitTransmitDescriptor(MACDriver *macp, systime_t time) { msg_t msg; + chDbgCheck((macp != NULL) && (tdp != NULL), "macWaitTransmitDescriptor"); + chDbgAssert(macp->state == MAC_ACTIVE, "macWaitTransmitDescriptor(), #1", + "not active"); + while (((msg = max_lld_get_transmit_descriptor(macp, tdp)) != RDY_OK) && (time > 0)) { chSysLock(); @@ -149,6 +178,8 @@ msg_t macWaitTransmitDescriptor(MACDriver *macp, */ void macReleaseTransmitDescriptor(MACTransmitDescriptor *tdp) { + chDbgCheck((tdp != NULL), "macReleaseTransmitDescriptor"); + mac_lld_release_transmit_descriptor(tdp); } @@ -176,6 +207,10 @@ msg_t macWaitReceiveDescriptor(MACDriver *macp, systime_t time) { msg_t msg; + chDbgCheck((macp != NULL) && (rdp != NULL), "macWaitReceiveDescriptor"); + chDbgAssert(macp->state == MAC_ACTIVE, "macWaitReceiveDescriptor(), #1", + "not active"); + while (((msg = max_lld_get_receive_descriptor(macp, rdp)) != RDY_OK) && (time > 0)) { chSysLock(); @@ -202,6 +237,8 @@ msg_t macWaitReceiveDescriptor(MACDriver *macp, */ void macReleaseReceiveDescriptor(MACReceiveDescriptor *rdp) { + chDbgCheck((rdp != NULL), "macReleaseReceiveDescriptor"); + mac_lld_release_receive_descriptor(rdp); } @@ -217,6 +254,10 @@ void macReleaseReceiveDescriptor(MACReceiveDescriptor *rdp) { */ bool_t macPollLinkStatus(MACDriver *macp) { + chDbgCheck((macp != NULL), "macPollLinkStatus"); + chDbgAssert(macp->state == MAC_ACTIVE, "macPollLinkStatus(), #1", + "not active"); + return mac_lld_poll_link_status(macp); } -- cgit v1.2.3