Forum: Mikrocontroller und Digitale Elektronik STM32F207 + KS8721 (Ethernet Phy)


von User (Gast)


Angehängte Dateien:

Lesenswert?

Guten Morgen,

für eine Anwendung habe ich eine Platine erstellt, auf der ein STM32F207 
Mikrocontroller und ein Ethernet Phy von Micrel KS8721 vorhanden ist.
Für die Nutzung der Ethernet MAC Komponente des Mikrocontrollers 
verwende ich die ST Bibliotheken. Die Konfiguration des Ethernet MAC DMA 
funktioniert nicht. Das Programm bleibt immer an folgender Stelle 
stehen:
1
while (ETH_GetSoftwareResetStatus() == SET);

Wenn ich allerdings die Clock-Konfiguration
1
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_ETH_MAC | RCC_AHB1Periph_ETH_MAC_Tx |
2
                       RCC_AHB1Periph_ETH_MAC_Rx, ENABLE);

erst nach der obigen while Bedingung ausführe, dann erfolgt ein 
Softwarereset.

Bevor ich diese Platine erstellt habe, benutzte ich ein Evaluationboard 
allerdings mit einem anderen Ethernet Phy von National Semiconductors 
DP83848C

Der Softwarereset bezieht sich dieser nur auf den STM32 ? Wenn 
möglicherweise der Phy nicht korrekt angeschlossen sein sollte, müsste 
nicht trotzdem der Softwarereset erfolgen ?

von User (Gast)


Lesenswert?

Hat hier keiner bereits den Mikrocontroller mit Ethernetschnittstelle in 
Betrieb genommen ?

von Star K. (starkeeper)


Lesenswert?

User schrieb:
> Hat hier keiner bereits den Mikrocontroller mit Ethernetschnittstelle in
> Betrieb genommen ?

Dein Problem ist spezieller als es dir vorkommen mag. Es gibt hunderte 
von Microcontrollern und auch hunderte von PHY's dafür. Vielleicht 
versuchst du mal selber dem Fehler auf den Grund zu gehen...  und dann 
lieferst du uns etwas detailreichere Informationen. Was fragt z.B. die 
Funktion ETH_GetSoftwareResetStatus() ab? Dahinter wird ja ein 
Registerzugriff stehen, entweder nur auf den lokalen uC oder auch auf 
den PHY. Du sagst du hast den PHY gewechselt, ich rate mal, dass du 
deinen PHY nicht korrekt einrichtest...

von Markus M. (Firma: EleLa - www.elela.de) (mmvisual)


Lesenswert?

Der DP83848C und KS8721 sind nahezu identisch, aber bei einem einzigen 
Befehl muss da was anderes während der Initialisierung (über die MDAT 
Leitung) was anderes geschrieben werden.
Ist schon ein paar Jahre her, daher weiß ich nicht mehr genau welcher 
Befehl es war.
Aber vergleiche mal beide Datenblätter, dann bekommst Du es raus.
Zumindest musste ich den Rest vom TCP/IP Stack nicht anpassen.

PS: ist wohl hier drin: "Eth_Link_PHYITConfig(DP83848_PHY_ADDRESS);"

von User (Gast)


Lesenswert?

Danke Markus,

die Adresse für DP83848_PHY_ADDRESS ist 0x01. Wie müsste die Adresse für 
den KS8721 lauten ?

Ich habe nach dem Softwarereset die ETH MAC Clock gesetzt. Nun kann ich 
so wie es aussieht auch den Phy auslesen bzw. beschreiben. Wie müsste 
nun eine Beispielkonfiguration lauten ? Welche Register bzw. Bit müsste 
ich in dem Phy setzen ?

von Markus M. (Firma: EleLa - www.elela.de) (mmvisual)


Angehängte Dateien:

Lesenswert?

Ich weiß es nicht mehr, ist schon mindestens 4 Jahre her.

Anbei mal ein Stück Quellcode, damals mit dem LPC2368 und µIP. 
Vielleicht hilft's. Wenn Du das hin bekommen hast, kannst Du mir den 
Code für den STM32 schicken?

von Bastler (Gast)


Lesenswert?

Bitte den Code hier veröffentlichen,
ich wäre stark daran interessiert.

von User (Gast)


Lesenswert?

Erstmal vielen Dank für die Datei. Leider bringt mir diese Datei auch 
nicht wesentlich weiter. Es fehlen hier die Definitionen von den 
einzelnen Macros. Welche PHY_ADDRESSE sollte verwendet werden ?

von User (Gast)


Lesenswert?

Wenn ich die PHY_ADDRESSE auf 0x20 anstatt 0x01 setze, dann kann ich 
Daten vom KS8721 empfangen. Bin mir da aber nicht sicher ob es doch die 
gespeicherten Daten vom ETH MAC des STM32 sind.

von User (Gast)


Lesenswert?

Ich habe nun alles mögliche im Netz durchsucht sowie die relevanten 
Stellen in den Datenblätter nachgeschaut. Wie muss der KS8721 (mit 
100MBit/s) exakt konfiguriert werden ?

von Markus M. (Firma: EleLa - www.elela.de) (mmvisual)


Lesenswert?

Damals hatte ich ein Demo hier gefunden, MT hat das jetzt aber nicht 
mehr drauf:
http://www.siwawi.arubi.uni-kl.de/avr_projects/arm_projects/

Ansonsten das Demo von ST laden. Oder woher hast Du Deinen Quellcode?

von Lothar (Gast)


Lesenswert?

User schrieb:
> Wie muss der KS8721 (mit
> 100MBit/s) exakt konfiguriert werden ?

Das hier ist ein Board mit genau STM32F207 + KS8721 und im Demo-Code zum 
Runterladen findest Du:

ethernet.c:
void tapdev_init(void)

https://www.olimex.com/Products/ARM/ST/STM32-P207

von User (Gast)


Lesenswert?

Hallo, ich habe nun auch das Beispiel von olimex angeschaut. Ich komme 
mit meiner Ethernet Applikation nicht weiter. So wie es aussieht kann 
ich die Register vom KS8721 Phy auslesen. Der Phy Identifier 1 hat den 
Wert: 0x22 sowie der Phy Identfier 2 hat den Wert: 0x1619. Also müsste 
dies schonmal funktionieren. Die Phy Adresse hat bei mir den Wert: 0x20.
Sobald ich ein Ethernet Frame versende (siehe folgende Funktion), wird 
in die if Anweisung gesprungen --> ETH_ERROR.
Was bedeutet dies ? Liegt es möglichweise am DmaTx Buffer ?
1
uint32_t ETH_HandleTxPkt(uint8_t *ppkt, uint16_t FrameLength)
2
{ 
3
  uint32_t offset = 0;
4
    
5
  /* Check if the descriptor is owned by the ETHERNET DMA (when set) or CPU (when reset) */
6
  if((DMATxDescToSet->Status & ETH_DMATxDesc_OWN) != (uint32_t)RESET)
7
  {
8
    /* Return ERROR: OWN bit set */
9
    return ETH_ERROR;
10
  }
11
  
12
  /* Copy the frame to be sent into memory pointed by the current ETHERNET DMA Tx descriptor */      
13
  for(offset=0; offset<FrameLength; offset++)       
14
  {
15
    (*(__IO uint8_t *)((DMATxDescToSet->Buffer1Addr) + offset)) = (*(ppkt + offset));
16
  }
17
        
18
  /* Setting the Frame Length: bits[12:0] */
19
  DMATxDescToSet->ControlBufferSize = (FrameLength & ETH_DMATxDesc_TBS1);
20
  /* Setting the last segment and first segment bits (in this case a frame is transmitted in one descriptor) */    
21
  DMATxDescToSet->Status |= ETH_DMATxDesc_LS | ETH_DMATxDesc_FS;
22
  /* Set Own bit of the Tx descriptor Status: gives the buffer back to ETHERNET DMA */
23
  DMATxDescToSet->Status |= ETH_DMATxDesc_OWN;
24
  /* When Tx Buffer unavailable flag is set: clear it and resume transmission */
25
  if ((ETH->DMASR & ETH_DMASR_TBUS) != (uint32_t)RESET)
26
  {
27
    /* Clear TBUS ETHERNET DMA flag */
28
    ETH->DMASR = ETH_DMASR_TBUS;
29
    /* Resume DMA transmission*/
30
    ETH->DMATPDR = 0;
31
  }
32
  
33
  /* Update the ETHERNET DMA global Tx descriptor with next Tx decriptor */  
34
  /* Chained Mode */
35
  if((DMATxDescToSet->Status & ETH_DMATxDesc_TCH) != (uint32_t)RESET)
36
  {     
37
    /* Selects the next DMA Tx descriptor list for next buffer to send */ 
38
    DMATxDescToSet = (ETH_DMADESCTypeDef*) (DMATxDescToSet->Buffer2NextDescAddr);    
39
  }
40
  else /* Ring Mode */
41
  {  
42
    if((DMATxDescToSet->Status & ETH_DMATxDesc_TER) != (uint32_t)RESET)
43
    {
44
      /* Selects the first DMA Tx descriptor for next buffer to send: last Tx descriptor was used */
45
      DMATxDescToSet = (ETH_DMADESCTypeDef*) (ETH->DMATDLAR);      
46
    }
47
    else
48
    {  
49
      /* Selects the next DMA Tx descriptor list for next buffer to send */
50
      DMATxDescToSet = (ETH_DMADESCTypeDef*) ((uint32_t)DMATxDescToSet + 0x10 + ((ETH->DMABMR & ETH_DMABMR_DSL) >> 2));      
51
    }
52
  }
53
  /* Return SUCCESS */
54
  return ETH_SUCCESS;   
55
}

Den Ethernet Clock kann ich nur nach dem Software Reset ausführen. Wenn 
ich vorher, wie in dem Olimex Beispiel gezeigt wird starte, komme ich 
über die while (ETH_GetSoftwareResetStatus() == SET); Schleife nicht 
hinaus.
1
  /* Wait for software reset */
2
  while (ETH_GetSoftwareResetStatus() == SET);
3
4
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_ETH_MAC | RCC_AHB1Periph_ETH_MAC_Tx |
5
  RCC_AHB1Periph_ETH_MAC_Rx, ENABLE);

von Lothar (Gast)


Lesenswert?

Hast Du DMA so wie in main.c initialisiert und die Funktionen in 
stm32_eth.c genutzt? Sind die Pins zwischen Deinem MCU und PHY dieselben 
wie bei Olimex? Hast Du alle Pins korrekt mit Pull-up/Pull-down versehen 
(siehe Olimex Schaltplan)? Läuft Dein 50 MHz Quarz? Leuchten an der 
Ethernet-Buchse die beiden LEDs beim Kabel einstecken?

von User (Gast)


Lesenswert?

Die Applikation von Olimex ist eine ganz andere. Da wird MII nicht 
verwendet. Ich nutze bzw. ich möchte MII benutzten.

Folgendes ist mir allerdings noch unklar. Muss Pin 45 (X0) ebenfalls an 
den 25 MHz Quarz angeschlossen werden ? Pin 46 (X1) ist an einem 
externen Quarz angeschlossen. Die Register vom KS8721 kann ich 
beschreiben und lesen.

Für Testzwecke setze ich das Evaluationboard von ST (Bezeichnung 
STM3220G-EVAL). Da wird nicht der Phy KS8721 verwendet. In der ST 
Library wird für die PHY Konfiguration diese Funktion eingesetzt.
1
#define DP83848_PHY_ADDRESS         0x01 /* Relative to STM322xG-EVAL Board */
2
3
/* Specific defines for EXTI line, used to manage Ethernet link status */
4
#define ETH_LINK_EXTI_LINE           EXTI_Line14
5
#define ETH_LINK_EXTI_PORT_SOURCE   EXTI_PortSourceGPIOB
6
#define ETH_LINK_EXTI_PIN_SOURCE    EXTI_PinSource14
7
#define ETH_LINK_EXTI_IRQn          EXTI15_10_IRQn
8
/* PB14 */
9
#define ETH_LINK_PIN                GPIO_Pin_14
10
#define ETH_LINK_GPIO_PORT          GPIOB
11
#define ETH_LINK_GPIO_CLK           RCC_AHB1Periph_GPIOB
12
/* PHY registers */
13
#define PHY_MICR                    0x1         /* MII Interrupt Control Register */
14
#define PHY_MICR_INT_EN             ((uint16_t)0x0002)  /* PHY Enable interrupts */
15
#define PHY_MICR_INT_OE             ((uint16_t)0x0001)  /* PHY Enable output interrupt events */
16
#define PHY_MISR                    0x1         /* MII Interrupt Status and Misc. Control Register */
17
#define PHY_MISR_LINK_INT_EN        ((uint16_t)0x0020)  /* Enable Interrupt on change of link status */
18
#define PHY_LINK_STATUS             ((uint16_t)0x2000)  /* PHY link status interrupt mask */
19
20
unsigned long Eth_Link_PHYITConfig(unsigned int PHYAddress)
21
{
22
  unsigned long tmpreg = 0;
23
24
  /* Read MICR register */
25
  tmpreg = ETH_ReadPHYRegister(PHYAddress, PHY_MICR);
26
27
  /* Enable output interrupt events to signal via the INT pin */
28
  tmpreg |= (unsigned long)PHY_MICR_INT_EN | PHY_MICR_INT_OE;
29
  if(!(ETH_WritePHYRegister(PHYAddress, PHY_MICR, tmpreg)))
30
  {
31
    /* Return ERROR in case of write timeout */
32
    return ETH_ERROR;
33
  }
34
35
  /* Read MISR register */
36
  tmpreg = ETH_ReadPHYRegister(PHYAddress, PHY_MISR);
37
38
  /* Enable Interrupt on change of link status */
39
  tmpreg |= (unsigned long)PHY_MISR_LINK_INT_EN;
40
  if(!(ETH_WritePHYRegister(PHYAddress, PHY_MISR, tmpreg)))
41
  {
42
    /* Return ERROR in case of write timeout */
43
    return ETH_ERROR;
44
  }
45
  /* Return SUCCESS */
46
  return ETH_SUCCESS;
47
}

Wie müsste ich diese Funktion für den PHY KS8721 anpassen ?

von Markus M. (mmax)


Lesenswert?

Hat jemand einen funktionierenden Code für den KS8721 hinbekommen ... 
wenn ja, könnte den bitte jemand posten. Ich stehe nämliche vor genau 
dem gleichen Problem.

Ich hab das E407 Board von Olimex und bekomm den lwIP Stack nicht zum 
laufen!

Danke,
Max

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.