git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3287 35acf78f-673a-0410-8e92-d51de3d6d3f4

This commit is contained in:
gdisirio 2011-09-03 12:35:41 +00:00
parent 08dad7b1f5
commit 792d85bcb5
6 changed files with 208 additions and 56 deletions

View File

@ -222,6 +222,7 @@ msg_t lwip_thread(void *p) {
EventListener el0, el1; EventListener el0, el1;
struct ip_addr ip, gateway, netmask; struct ip_addr ip, gateway, netmask;
static struct netif thisif; static struct netif thisif;
static const MACConfig mac_config = {thisif.hwaddr};
/* Initializes the thing.*/ /* Initializes the thing.*/
sys_init(); sys_init();
@ -254,7 +255,7 @@ msg_t lwip_thread(void *p) {
LWIP_GATEWAY(&gateway); LWIP_GATEWAY(&gateway);
LWIP_NETMASK(&netmask); LWIP_NETMASK(&netmask);
} }
macSetAddress(&ETH1, thisif.hwaddr); macStart(&ETH1, &mac_config);
netif_add(&thisif, &ip, &netmask, &gateway, NULL, ethernetif_init, tcpip_input); netif_add(&thisif, &ip, &netmask, &gateway, NULL, ethernetif_init, tcpip_input);
netif_set_default(&thisif); netif_set_default(&thisif);

View File

@ -38,18 +38,48 @@
/* Driver pre-compile time settings. */ /* 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. */ /* Derived constants and error checks. */
/*===========================================================================*/ /*===========================================================================*/
#if !CH_USE_SEMAPHORES || !CH_USE_EVENTS #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 #endif
/*===========================================================================*/ /*===========================================================================*/
/* Driver data structures and types. */ /* 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" #include "mac_lld.h"
/*===========================================================================*/ /*===========================================================================*/
@ -68,7 +98,7 @@
* *
* @api * @api
*/ */
#if CH_USE_EVENTS || defined(__DOXYGEN__) #if MAC_USE_EVENTS || defined(__DOXYGEN__)
#define macGetReceiveEventSource(macp) (&(macp)->rdevent) #define macGetReceiveEventSource(macp) (&(macp)->rdevent)
#endif #endif
@ -113,6 +143,8 @@ extern "C" {
#endif #endif
void macInit(void); void macInit(void);
void macObjectInit(MACDriver *macp); void macObjectInit(MACDriver *macp);
void macStart(MACDriver *macp, const MACConfig *config);
void macStop(MACDriver *macp);
void macSetAddress(MACDriver *macp, const uint8_t *p); void macSetAddress(MACDriver *macp, const uint8_t *p);
msg_t macWaitTransmitDescriptor(MACDriver *macp, msg_t macWaitTransmitDescriptor(MACDriver *macp,
MACTransmitDescriptor *tdp, MACTransmitDescriptor *tdp,

View File

@ -64,7 +64,6 @@ MACDriver ETH1;
/*===========================================================================*/ /*===========================================================================*/
#ifndef __DOXYGEN__ #ifndef __DOXYGEN__
static bool_t link_up;
static uint8_t default_mac[] = {0xAA, 0x55, 0x13, 0x37, 0x01, 0x10}; 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) { if (rsr & AT91C_EMAC_REC) {
chSysLockFromIsr(); chSysLockFromIsr();
chSemResetI(&ETH1.rdsem, 0); chSemResetI(&ETH1.rdsem, 0);
#if CH_USE_EVENTS #if MAC_USE_EVENTS
chEvtBroadcastI(&ETH1.rdevent); chEvtBroadcastI(&ETH1.rdevent);
#endif #endif
chSysUnlockFromIsr(); 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. */ /* Driver interrupt handlers. */
/*===========================================================================*/ /*===========================================================================*/
@ -163,11 +175,34 @@ CH_IRQ_HANDLER(irq_handler) {
* @notapi * @notapi
*/ */
void mac_lld_init(void) { void mac_lld_init(void) {
unsigned i;
miiInit(); miiInit();
macObjectInit(&ETH1); macObjectInit(&ETH1);
/*
* Associated PHY initialization.
*/
miiReset(&ETH1);
/*
* 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. * Buffers initialization.
*/ */
@ -185,18 +220,9 @@ void mac_lld_init(void) {
txptr = td; txptr = td;
/* /*
* Associated PHY initialization. * EMAC clock enable.
*/
miiReset(&ETH1);
/*
* EMAC pins setup and clock enable. Note, PB18 is not included because it is
* used as #PD control and not as EF100.
*/ */
AT91C_BASE_PMC->PMC_PCER = 1 << AT91C_ID_EMAC; 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. * EMAC Initial setup.
@ -213,7 +239,10 @@ void mac_lld_init(void) {
AT91C_BASE_EMAC->EMAC_NCR |= AT91C_EMAC_TE | AT91C_BASE_EMAC->EMAC_NCR |= AT91C_EMAC_TE |
AT91C_EMAC_RE | AT91C_EMAC_RE |
AT91C_EMAC_CLRSTAT;/* Initial NCR settings.*/ AT91C_EMAC_CLRSTAT;/* Initial NCR settings.*/
mac_lld_set_address(&ETH1, default_mac); if (macp->config->mac_address == NULL)
set_address(default_mac);
else
set_address(macp->config->mac_address);
/* /*
* PHY device identification. * 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] 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 * @notapi
*/ */
void mac_lld_set_address(MACDriver *macp, const uint8_t *p) { void mac_lld_stop(MACDriver *macp) {
(void)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; (void)macp;
if (!link_up) if (!macp->link_up)
return RDY_TIMEOUT; return RDY_TIMEOUT;
chSysLock(); chSysLock();
@ -505,7 +527,7 @@ bool_t mac_lld_poll_link_status(MACDriver *macp) {
bmsr = miiGet(macp, MII_BMSR); bmsr = miiGet(macp, MII_BMSR);
if (!(bmsr & BMSR_LSTATUS)) { if (!(bmsr & BMSR_LSTATUS)) {
AT91C_BASE_EMAC->EMAC_NCR &= ~AT91C_EMAC_MPE; 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); 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_NCFGR = ncfgr;
AT91C_BASE_EMAC->EMAC_NCR &= ~AT91C_EMAC_MPE; AT91C_BASE_EMAC->EMAC_NCR &= ~AT91C_EMAC_MPE;
return link_up = TRUE; return macp->link_up = TRUE;
} }
#endif /* HAL_USE_MAC */ #endif /* HAL_USE_MAC */

View File

@ -128,38 +128,85 @@ typedef struct {
} EMACDescriptor; } EMACDescriptor;
/** /**
* @brief Structure representing a MAC driver. * @brief Driver configuration structure.
*/ */
typedef struct { typedef struct {
Semaphore tdsem; /**< Transmit semaphore. */ /**
Semaphore rdsem; /**< Receive semaphore. */ * @brief MAC address.
#if CH_USE_EVENTS */
EventSource rdevent; /**< Receive event source. */ 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 #endif
/* End of the mandatory fields.*/ /* End of the mandatory fields.*/
} MACDriver; /**
* @brief Link status flag.
*/
bool_t link_up;
};
/** /**
* @brief Structure representing a transmit descriptor. * @brief Structure representing a transmit descriptor.
*/ */
typedef struct { 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.*/ /* End of the mandatory fields.*/
EMACDescriptor *physdesc; /**< Pointer to the physical /**
descriptor. */ * @brief Pointer to the physical descriptor.
*/
EMACDescriptor *physdesc;
} MACTransmitDescriptor; } MACTransmitDescriptor;
/** /**
* @brief Structure representing a receive descriptor. * @brief Structure representing a receive descriptor.
*/ */
typedef struct { 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.*/ /* End of the mandatory fields.*/
EMACDescriptor *physdesc; /**< Pointer to the first /**
descriptor of the buffers * @brief Pointer to the first descriptor of the buffers chain.
chain. */ */
EMACDescriptor *physdesc;
} MACReceiveDescriptor; } MACReceiveDescriptor;
/*===========================================================================*/ /*===========================================================================*/
@ -178,7 +225,8 @@ extern MACDriver ETH1;
extern "C" { extern "C" {
#endif #endif
void mac_lld_init(void); 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, msg_t max_lld_get_transmit_descriptor(MACDriver *macp,
MACTransmitDescriptor *tdp); MACTransmitDescriptor *tdp);
size_t mac_lld_write_transmit_descriptor(MACTransmitDescriptor *tdp, size_t mac_lld_write_transmit_descriptor(MACTransmitDescriptor *tdp,

View File

@ -21,8 +21,6 @@
/** /**
* @file mac.c * @file mac.c
* @brief MAC Driver code. * @brief MAC Driver code.
* @note This function is implicitly invoked by @p halInit(), there is
* no need to explicitly initialize the driver.
* *
* @addtogroup MAC * @addtogroup MAC
* @{ * @{
@ -59,6 +57,8 @@
/** /**
* @brief MAC Driver initialization. * @brief MAC Driver initialization.
* @note This function is implicitly invoked by @p halInit(), there is
* no need to explicitly initialize the driver.
* *
* @init * @init
*/ */
@ -76,28 +76,53 @@ void macInit(void) {
*/ */
void macObjectInit(MACDriver *macp) { void macObjectInit(MACDriver *macp) {
macp->state = MAC_STOP;
macp->config = NULL;
chSemInit(&macp->tdsem, 0); chSemInit(&macp->tdsem, 0);
chSemInit(&macp->rdsem, 0); chSemInit(&macp->rdsem, 0);
#if CH_USE_EVENTS #if MAC_USE_EVENTS
chEvtInit(&macp->rdevent); chEvtInit(&macp->rdevent);
#endif #endif
} }
/** /**
* @brief MAC address setup. * @brief Configures and activates the MAC peripheral.
* @pre This function must be invoked with the driver in the stopped
* state. If invoked on an active interface then it is ignored.
* *
* @param[in] macp pointer to the @p MACDriver object * @param[in] macp pointer to the @p MACDriver object
* @param[in] p pointer to a six bytes buffer containing the MAC * @param[in] config pointer to the @p MACConfig object
* address. If this parameter is set to @p NULL then MAC
* a system default is used.
* *
* @api * @api
*/ */
void macSetAddress(MACDriver *macp, const uint8_t *p) { void macStart(MACDriver *macp, const MACConfig *config) {
mac_lld_set_address(macp, p); 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
*
* @api
*/
void macStop(MACDriver *macp) {
chDbgCheck(macp != NULL, "macStop");
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) { systime_t time) {
msg_t msg; 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) && while (((msg = max_lld_get_transmit_descriptor(macp, tdp)) != RDY_OK) &&
(time > 0)) { (time > 0)) {
chSysLock(); chSysLock();
@ -149,6 +178,8 @@ msg_t macWaitTransmitDescriptor(MACDriver *macp,
*/ */
void macReleaseTransmitDescriptor(MACTransmitDescriptor *tdp) { void macReleaseTransmitDescriptor(MACTransmitDescriptor *tdp) {
chDbgCheck((tdp != NULL), "macReleaseTransmitDescriptor");
mac_lld_release_transmit_descriptor(tdp); mac_lld_release_transmit_descriptor(tdp);
} }
@ -176,6 +207,10 @@ msg_t macWaitReceiveDescriptor(MACDriver *macp,
systime_t time) { systime_t time) {
msg_t msg; 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) && while (((msg = max_lld_get_receive_descriptor(macp, rdp)) != RDY_OK) &&
(time > 0)) { (time > 0)) {
chSysLock(); chSysLock();
@ -202,6 +237,8 @@ msg_t macWaitReceiveDescriptor(MACDriver *macp,
*/ */
void macReleaseReceiveDescriptor(MACReceiveDescriptor *rdp) { void macReleaseReceiveDescriptor(MACReceiveDescriptor *rdp) {
chDbgCheck((rdp != NULL), "macReleaseReceiveDescriptor");
mac_lld_release_receive_descriptor(rdp); mac_lld_release_receive_descriptor(rdp);
} }
@ -217,6 +254,10 @@ void macReleaseReceiveDescriptor(MACReceiveDescriptor *rdp) {
*/ */
bool_t macPollLinkStatus(MACDriver *macp) { 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); return mac_lld_poll_link_status(macp);
} }

View File

@ -89,6 +89,14 @@
(backported to 2.2.4). (backported to 2.2.4).
- FIX: Fixed timeout problem in the lwIP interface layer (bug 3302420) - FIX: Fixed timeout problem in the lwIP interface layer (bug 3302420)
(backported to 2.2.4). (backported to 2.2.4).
- NEW: New I2C driver model and STM32 implementation.
(evaluate the option to change the API to a synchronous model)
- NEW: New RTC driver model and STM32 implementation.
(API and functionality review)
- NEW: Improved MAC driver model, it now follows the same template of other
drivers.
(uIP demo to be adapted)
(implement macStop() in AT91SAM7X implementation)
- NEW: New DMA helper driver for STM32, it simplifies the use of the DMA - NEW: New DMA helper driver for STM32, it simplifies the use of the DMA
resources and hides most differences with the new enhanced DMA units resources and hides most differences with the new enhanced DMA units
found in the STM32F2xx sub-family. found in the STM32F2xx sub-family.