aboutsummaryrefslogtreecommitdiffstats
path: root/os/hal
diff options
context:
space:
mode:
authorgdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4>2012-02-22 15:29:44 +0000
committergdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4>2012-02-22 15:29:44 +0000
commit209d46893b8a55f1bc2b9dd3db0d807d250e49de (patch)
treecdb4199acb08e978a8d405f33d9354922bb0a64f /os/hal
parentb97d65b80fed63a5f31097652f9556659c2338d7 (diff)
downloadChibiOS-209d46893b8a55f1bc2b9dd3db0d807d250e49de.tar.gz
ChibiOS-209d46893b8a55f1bc2b9dd3db0d807d250e49de.tar.bz2
ChibiOS-209d46893b8a55f1bc2b9dd3db0d807d250e49de.zip
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3969 35acf78f-673a-0410-8e92-d51de3d6d3f4
Diffstat (limited to 'os/hal')
-rw-r--r--os/hal/platforms/STM32/mac_lld.c107
-rw-r--r--os/hal/platforms/STM32/mac_lld.h4
2 files changed, 99 insertions, 12 deletions
diff --git a/os/hal/platforms/STM32/mac_lld.c b/os/hal/platforms/STM32/mac_lld.c
index 67f04f12e..ee08189bb 100644
--- a/os/hal/platforms/STM32/mac_lld.c
+++ b/os/hal/platforms/STM32/mac_lld.c
@@ -142,6 +142,7 @@ void mac_lld_init(void) {
unsigned i;
macObjectInit(&ETHD1);
+ ETHD1.link_up = FALSE;
/* Descriptor tables are initialized in linked mode, note that the first
word is not initialized here but in mac_lld_start().*/
@@ -205,23 +206,56 @@ void mac_lld_start(MACDriver *macp) {
/* MAC clocks activation.*/
rccEnableETH(FALSE);
- /* Descriptor chains pointers.*/
- ETH->DMARDLAR = (uint32_t)rd;
- ETH->DMATDLAR = (uint32_t)rd;
-
/* MAC configuration:
- ETH_MACCR_TE - Transmitter enable.
- ETH_MACCR_RE - Receiver enable.
- Note that the complete setup of the MAC is performed when the link
- status is detected.*/
- ETH->MACCR = ETH_MACCR_TE | ETH_MACCR_TE;
-
- ETH->MACFFR = 0;
+ ETH_MACFFR_SAF - Source address filter. Broadcast frames are not
+ filtered.*/
+ ETH->MACFFR = ETH_MACFFR_SAF;
+
+ /* MAC address configuration, only a single address comparator is used,
+ hash table not used.*/
+ ETH->MACA0HR = ((uint32_t)macp->config->mac_address[0] << 8) |
+ ((uint32_t)macp->config->mac_address[1] << 0);
+ ETH->MACA0LR = ((uint32_t)macp->config->mac_address[2] << 24) |
+ ((uint32_t)macp->config->mac_address[3] << 16) |
+ ((uint32_t)macp->config->mac_address[4] << 8) |
+ ((uint32_t)macp->config->mac_address[5] << 0);
+ ETH->MACA1HR = 0x0000FFFF;
+ ETH->MACA1LR = 0xFFFFFFFF;
+ ETH->MACA2HR = 0x0000FFFF;
+ ETH->MACA2LR = 0xFFFFFFFF;
+ ETH->MACA3HR = 0x0000FFFF;
+ ETH->MACA3LR = 0xFFFFFFFF;
ETH->MACHTHR = 0;
ETH->MACHTLR = 0;
- ETH->MACHTLR = 0;
+
+ /* MAC flow control not used, VLAN not used.*/
ETH->MACFCR = 0;
ETH->MACVLANTR = 0;
+
+ /* Transmitter and receiver enabled.
+ Note that the complete setup of the MAC is performed when the link
+ status is detected.*/
+ ETH->MACCR = ETH_MACCR_TE | ETH_MACCR_TE;
+
+ /* DMA configuration:
+ Descriptor chains pointers.*/
+ ETH->DMARDLAR = (uint32_t)rd;
+ ETH->DMATDLAR = (uint32_t)td;
+
+ /* Enabling required interrupt sources.*/
+ ETH->DMASR = 0xFFFFFFFF; /* Resetting pending flags. */
+
+ /* DMA general settings.*/
+ ETH->DMABMR = ETH_DMABMR_AAB | ETH_DMABMR_RDP_1Beat | ETH_DMABMR_PBL_1Beat;
+
+ /* Transmit FIFO flush.*/
+ ETH->DMAOMR = ETH_DMAOMR_FTF;
+ while (ETH->DMAOMR & ETH_DMAOMR_FTF)
+ ;
+
+ /* DMA final configuration and start.*/
+ ETH->DMAOMR = ETH_DMAOMR_DTCEFD | ETH_DMAOMR_RSF | ETH_DMAOMR_TSF |
+ ETH_DMAOMR_ST | ETH_DMAOMR_SR;
}
/**
@@ -350,7 +384,56 @@ void mac_lld_release_receive_descriptor(MACReceiveDescriptor *rdp) {
* @notapi
*/
bool_t mac_lld_poll_link_status(MACDriver *macp) {
+ uint32_t maccr, bmsr, bmcr;
+
+ /* Checks if the link is up, updates the status accordingly and returns.*/
+ bmsr = mii_read_phy(MII_BMSR);
+ if (!(bmsr & BMSR_LSTATUS))
+ return macp->link_up = FALSE;
+
+ maccr = ETH->MACCR;
+ bmcr = mii_read_phy(MII_BMCR);
+
+ /* Check on auto-negotiation mode.*/
+ if (bmcr & BMCR_ANENABLE) {
+ uint32_t lpa;
+
+ /* Auto-nogotiation enabled, checks the LPA register.*/
+ lpa = mii_read_phy(MII_LPA);
+
+ /* Check on link speed.*/
+ if (lpa & (LPA_100HALF | LPA_100FULL | LPA_100BASE4))
+ maccr |= ETH_MACCR_FES;
+ else
+ maccr &= ~ETH_MACCR_FES;
+
+ /* Check on link mode.*/
+ if (lpa & (LPA_10FULL | LPA_100FULL))
+ maccr |= ETH_MACCR_DM;
+ else
+ maccr &= ~ETH_MACCR_DM;
+ }
+ else {
+ /* Auto-negotiation disabled, checks the current settings.*/
+
+ /* Check on link speed.*/
+ if (bmcr & BMCR_SPEED100)
+ maccr |= ETH_MACCR_FES;
+ else
+ maccr &= ~ETH_MACCR_FES;
+
+ /* Check on link mode.*/
+ if (bmcr & BMCR_FULLDPLX)
+ maccr |= ETH_MACCR_DM;
+ else
+ maccr &= ~ETH_MACCR_DM;
+ }
+
+ /* Changes the mode in the MAC.*/
+ ETH->MACCR = maccr;
+ /* Returns the link status.*/
+ return macp->link_up = TRUE;
}
#endif /* HAL_USE_MAC */
diff --git a/os/hal/platforms/STM32/mac_lld.h b/os/hal/platforms/STM32/mac_lld.h
index d3db90893..86d059d42 100644
--- a/os/hal/platforms/STM32/mac_lld.h
+++ b/os/hal/platforms/STM32/mac_lld.h
@@ -206,6 +206,10 @@ struct MACDriver {
EventSource rdevent;
#endif
/* End of the mandatory fields.*/
+ /**
+ * @brief Link status flag.
+ */
+ bool_t link_up;
};
/**