Discussion:
About stm32f107 use dm9161
(too old to reply)
darcygong
2012-08-28 04:25:49 UTC
Permalink
hi all:
I shenzhou iv stm32f107 a development board, board dm9161 Ethernet phy chip RMII work mode.Configured and compiled, nsh shell work, eth0 not found the device in the /dev/ (nsh shell), also can not ping.Advice on how to determine the problems and solutions. Thank!
tips are as follows

NuttShell (NSH)
nsh> ls dev
/dev:
console
null
ttyS0
nsh> ADE
netdev_register: Registered MAC: 00:00:00:00:00:00 as dev: eth0
netdev_ifrioctl: cmd:stm32_ethconfig: Reset the Ethernet block
stm32_ethconfig: Initialize the PHY
1803
netdev_ifrioctl: cmd: 1794
stm32_ifdown: Taking the network down
stm32_ifup: Bringing up: 192.168.150.56
stm32_phyinit: PHYVAL: 385 | 181
stm32_phyinit: Find PHY: DM9161AEP
stm32_phstm32_ethconfig: Initialize the MAC and DMA
stm32_ethconfig: Enable normal operation
stm32_macaddress: eth0 MAC: 00:e0:de:ad:be:ef
yinit: Duplex: FULL Stelnetd_daemon: Accepting connections on port 23
peed: 100 MBps
netdev_ifrioctl: cmd: 1796
netdev_ifrioctl: cmd: 1800
nsh_telnetstart: Starting the Telnet daemon

NuttShell (NSH)
nsh>
Gregory N
2012-08-28 12:46:17 UTC
Permalink
Hi, Shenzhou,
Post by darcygong
I shenzhou iv stm32f107 a development board, board dm9161 Ethernet phy chip RMII work mode.Configured and compiled, nsh shell work, eth0 not found the device in the /dev/ (nsh shell), also can not ping.Advice on how to determine the problems and solutions. Thank!
tips are as follows
NuttShell (NSH)
nsh> ls dev
console
null
ttyS0
nsh> ADE
netdev_register: Registered MAC: 00:00:00:00:00:00 as dev: eth0
netdev_ifrioctl: cmd:stm32_ethconfig: Reset the Ethernet block
stm32_ethconfig: Initialize the PHY
1803
netdev_ifrioctl: cmd: 1794
stm32_ifdown: Taking the network down
stm32_ifup: Bringing up: 192.168.150.56
stm32_phyinit: PHYVAL: 385 | 181
stm32_phyinit: Find PHY: DM9161AEP
stm32_phstm32_ethconfig: Initialize the MAC and DMA
stm32_ethconfig: Enable normal operation
stm32_macaddress: eth0 MAC: 00:e0:de:ad:be:ef
yinit: Duplex: FULL Stelnetd_daemon: Accepting connections on port 23
peed: 100 MBps
netdev_ifrioctl: cmd: 1796
netdev_ifrioctl: cmd: 1800
nsh_telnetstart: Starting the Telnet daemon
NuttShell (NSH)
nsh>
This output all looks good. I do not see any problems in the network initialization. Perhaps your problems only occur later when you begin passing packets?

I do not have an F107 board and have not worked with the F107 Ethernet peripheral at all. I have the Ethernet driver working will on an F207 and an F407 board, but I think that there must be some difference with the F107 Ethernet peripheral.

Other people have reported problems with the Ethernet driver with the F107. See http://tech.groups.yahoo.com/group/nuttx/message/1893. There are some minor differences with the peripheral registers and bits, but the F107 and F207/F407 seem compatible.

The working Ethernet on the F207/F407 boards use a DP83848C PHY.

Sorry that I cannot be of more help to you.

Greg
darcygong
2012-08-29 16:30:44 UTC
Permalink
Post by Gregory N
Hi, Shenzhou,
Post by darcygong
I shenzhou iv stm32f107 a development board, board dm9161 Ethernet phy chip RMII work mode.Configured and compiled, nsh shell work, eth0 not found the device in the /dev/ (nsh shell), also can not ping.Advice on how to determine the problems and solutions. Thank!
tips are as follows
NuttShell (NSH)
nsh> ls dev
console
null
ttyS0
nsh> ADE
netdev_register: Registered MAC: 00:00:00:00:00:00 as dev: eth0
netdev_ifrioctl: cmd:stm32_ethconfig: Reset the Ethernet block
stm32_ethconfig: Initialize the PHY
1803
netdev_ifrioctl: cmd: 1794
stm32_ifdown: Taking the network down
stm32_ifup: Bringing up: 192.168.150.56
stm32_phyinit: PHYVAL: 385 | 181
stm32_phyinit: Find PHY: DM9161AEP
stm32_phstm32_ethconfig: Initialize the MAC and DMA
stm32_ethconfig: Enable normal operation
stm32_macaddress: eth0 MAC: 00:e0:de:ad:be:ef
yinit: Duplex: FULL Stelnetd_daemon: Accepting connections on port 23
peed: 100 MBps
netdev_ifrioctl: cmd: 1796
netdev_ifrioctl: cmd: 1800
nsh_telnetstart: Starting the Telnet daemon
NuttShell (NSH)
nsh>
This output all looks good. I do not see any problems in the network initialization. Perhaps your problems only occur later when you begin passing packets?
I do not have an F107 board and have not worked with the F107 Ethernet peripheral at all. I have the Ethernet driver working will on an F207 and an F407 board, but I think that there must be some difference with the F107 Ethernet peripheral.
Other people have reported problems with the Ethernet driver with the F107. See http://tech.groups.yahoo.com/group/nuttx/message/1893. There are some minor differences with the peripheral registers and bits, but the F107 and F207/F407 seem compatible.
The working Ethernet on the F207/F407 boards use a DP83848C PHY.
Sorry that I cannot be of more help to you.
Greg
Hi Greg,
The source code I've patched. My development board Ethernet initialization properly, but there is no connection from the PC can not ping the target machine. I checked all the PHY address, and to ensure that the register address register configuration and development board Demo application consistent.But the network still does not work. If you can help find the problem, I can provide the development board to you (give me your address, I express to you).My development board Demo program is a Chinese output.Should not interfere with your the research.

Darcy
Max Holtzberg
2012-08-28 20:27:13 UTC
Permalink
Post by darcygong
I shenzhou iv stm32f107 a development board, board dm9161 Ethernet phy chip RMII work mode.Configured and compiled, nsh shell work, eth0 not found the device in the /dev/ (nsh shell), also can not ping.Advice on how to determine the problems and solutions. Thank!
tips are as follows
NuttShell (NSH)
nsh> ls dev
console
null
ttyS0
nsh> ADE
netdev_register: Registered MAC: 00:00:00:00:00:00 as dev: eth0
netdev_ifrioctl: cmd:stm32_ethconfig: Reset the Ethernet block
stm32_ethconfig: Initialize the PHY
1803
netdev_ifrioctl: cmd: 1794
stm32_ifdown: Taking the network down
stm32_ifup: Bringing up: 192.168.150.56
stm32_phyinit: PHYVAL: 385 | 181
stm32_phyinit: Find PHY: DM9161AEP
stm32_phstm32_ethconfig: Initialize the MAC and DMA
stm32_ethconfig: Enable normal operation
stm32_macaddress: eth0 MAC: 00:e0:de:ad:be:ef
yinit: Duplex: FULL Stelnetd_daemon: Accepting connections on port 23
peed: 100 MBps
netdev_ifrioctl: cmd: 1796
netdev_ifrioctl: cmd: 1800
nsh_telnetstart: Starting the Telnet daemon
NuttShell (NSH)
nsh>
Hi,

I also tried to get Ethernet working on a stm32f107.
Do you get "stm32_interrupt: Abormal event(s): 00008080" too?
(Maybe with CONFIG_DEBUG_VERBOSE=y)

I had no time yet to investigate that further...

Max
darcygong
2012-08-29 16:03:40 UTC
Permalink
Post by Max Holtzberg
Post by darcygong
I shenzhou iv stm32f107 a development board, board dm9161 Ethernet phy chip RMII work mode.Configured and compiled, nsh shell work, eth0 not found the device in the /dev/ (nsh shell), also can not ping.Advice on how to determine the problems and solutions. Thank!
tips are as follows
NuttShell (NSH)
nsh> ls dev
console
null
ttyS0
nsh> ADE
netdev_register: Registered MAC: 00:00:00:00:00:00 as dev: eth0
netdev_ifrioctl: cmd:stm32_ethconfig: Reset the Ethernet block
stm32_ethconfig: Initialize the PHY
1803
netdev_ifrioctl: cmd: 1794
stm32_ifdown: Taking the network down
stm32_ifup: Bringing up: 192.168.150.56
stm32_phyinit: PHYVAL: 385 | 181
stm32_phyinit: Find PHY: DM9161AEP
stm32_phstm32_ethconfig: Initialize the MAC and DMA
stm32_ethconfig: Enable normal operation
stm32_macaddress: eth0 MAC: 00:e0:de:ad:be:ef
yinit: Duplex: FULL Stelnetd_daemon: Accepting connections on port 23
peed: 100 MBps
netdev_ifrioctl: cmd: 1796
netdev_ifrioctl: cmd: 1800
nsh_telnetstart: Starting the Telnet daemon
NuttShell (NSH)
nsh>
Hi,
I also tried to get Ethernet working on a stm32f107.
Do you get "stm32_interrupt: Abormal event(s): 00008080" too?
(Maybe with CONFIG_DEBUG_VERBOSE=y)
I had no time yet to investigate that further...
Max
Hi, Max.
I open the debug, but did not find this error message you said. The development board you are now able to work?

Darcy
Gregory N
2012-08-29 16:25:05 UTC
Permalink
Hi, Shenzhou
Post by darcygong
Post by Max Holtzberg
I shenzhou iv stm32f107 a development board, board dm9161 Ethernet phy chip RMII work mode.Configured and compiled, nsh shell work, eth0 not found the device in the /dev/ (nsh shell), also can not ping....
Ethernet devices are not like other devices. They never appear in /dev/ because there is no special file associated with them.

The NSH command 'ifconfig' will how information about the status of Ethernet.
Post by darcygong
Post by Max Holtzberg
... Advice on how to determine the problems and solutions. Thank!
As I mentioned before, the debug output when Ethernet starts looks good, I don't see any problems there. The problem must occur later when you use Ethernet.
Post by darcygong
Post by Max Holtzberg
tips are as follows
... [snip] ...
I also tried to get Ethernet working on a stm32f107.
Do you get "stm32_interrupt: Abormal event(s): 00008080" too?
(Maybe with CONFIG_DEBUG_VERBOSE=y)
I had no time yet to investigate that further...
Max
Hi, Max.
I open the debug, but did not find this error message you said. The development board you are now able to work?
You said that ping does not work. What kind of debug output do you see when you do the ping. What kind of error messages do you see when you ping?

Normal debug output is enabled with:

CONFIG_DEBUG=y
CONFIG_DEBUG_VERBOSE=y
CONFIG_DEBUG_NET=y

Other very verbose debug options can also be used:

CONFIG_STM32_ETHMAC_REGDEBUG=y Will show every register access.

Greg
darcygong
2012-08-29 16:46:34 UTC
Permalink
Post by Gregory N
Hi, Shenzhou
Post by darcygong
Post by Max Holtzberg
I shenzhou iv stm32f107 a development board, board dm9161 Ethernet phy chip RMII work mode.Configured and compiled, nsh shell work, eth0 not found the device in the /dev/ (nsh shell), also can not ping....
Ethernet devices are not like other devices. They never appear in /dev/ because there is no special file associated with them.
The NSH command 'ifconfig' will how information about the status of Ethernet.
the ifconfig output information is normal.
Post by Gregory N
Post by darcygong
Post by Max Holtzberg
... Advice on how to determine the problems and solutions. Thank!
As I mentioned before, the debug output when Ethernet starts looks good, I don't see any problems there. The problem must occur later when you use Ethernet.
Post by darcygong
Post by Max Holtzberg
tips are as follows
... [snip] ...
I also tried to get Ethernet working on a stm32f107.
Do you get "stm32_interrupt: Abormal event(s): 00008080" too?
(Maybe with CONFIG_DEBUG_VERBOSE=y)
I had no time yet to investigate that further...
Max
Hi, Max.
I open the debug, but did not find this error message you said. The development board you are now able to work?
You said that ping does not work. What kind of debug output do you see when you do the ping. What kind of error messages do you see when you ping?
I am in China, now the time is the middle of the night 1:00.So I can only tomorrow output debugging information to you.If you can give me the address, and tomorrow I will send a STM32F107 development board to you
Post by Gregory N
CONFIG_DEBUG=y
CONFIG_DEBUG_VERBOSE=y
CONFIG_DEBUG_NET=y
CONFIG_STM32_ETHMAC_REGDEBUG=y Will show every register access.
Yesterday, I opened CONFIG_STM32_ETHMAC_REGDEBUG = y, but too much information, I do not have the correct MAC register configuration.Temporarily unable to find the problem.
Post by Gregory N
Greg
Darcy. PS: my name is "Darcy",my development board name is "ShenZhou", ;-)
Gregory N
2012-08-29 16:54:37 UTC
Permalink
Hi, Darcy,
Post by darcygong
I am in China, now the time is the middle of the night 1:00.So I can only tomorrow output debugging information to you.If you can give me the address, and tomorrow I will send a STM32F107 development board to you
I will send my address in a personal email.
Post by darcygong
Darcy. PS: my name is "Darcy",my development board name is "ShenZhou", ;-)
That is funny. My apologies.

Greg
darcygong
2012-08-29 17:57:23 UTC
Permalink
hi Greg,
My Board Debug messages:
netdev_register: Registered MAC: 00:00:00:00:00:00 as dev: eth0
netdev_ifrioctl: cmd: 1803
netdev_ifrioctl: cmd: stm32_ethconfig: Reset the Ethernet block
stm32_ethconfig: Initialize the PHY
1794
stm32_ifdown: Taking the network down
stm32_ifup: Bringing up: 192.168.150.56
stm32_phyinit: PHYVAL: 385 | 0x0181
stm32_phyinit: Find PHY: DM9161AEP
stm32_phyinit: Find PHY: DM9161AEP MII_MSR_LINKSTATUS 0x0000784d ok
stm32_phyinit: Read the PHY MSR: 30797 | 0x0000784d
stm32_phyinit: Read2 the PHY MSR: 30829 | 0x0000786d
stm32_phyinit: read PHY status register: 0x00000514 | 0x00000100
stm32_phyinit: Duplex: FULL Speed: 100 MBps
stm32_ethconfig: Initialize the MAC and DMA
stm32_ethconfig: Enable normal operation
dump_netinfo: id=0 PHYVAL: 0x00003100
dump_netinfo: id=1 PHYVAL: 0x0000786d
dump_netinfo: id=2 PHYVAL: 0x00000181
dump_netinfo: id=3 PHYVAL: 0x0000b8a0
dump_netinfo: id=4 PHYVAL: 0x000001e1
dump_netinfo: id=5 PHYVAL: 0x00004de1
dump_netinfo: id=6 PHYVAL: 0x00000003
dump_netinfo: id=7 PHYVAL: 0x00000000
dump_netinfo: id=8 PHYVAL: 0x00000000
dump_netinfo: id=9 PHYVAL: 0x00000000
dump_netinfo: id=10 PHYVAL: 0x00000000
dump_netinfo: id=11 PHYVAL: 0x00000000
dump_netinfo: id=12 PHYVAL: 0x00000000
dump_netinfo: id=13 PHYVAL: 0x00000000
dump_netinfo: id=14 PHYVAL: 0x00000000
dump_netinfo: id=15 PHYVAL: 0x00000000
dump_netinfo: id=16 PHYVAL: 0x00000514
dump_netinfo: id=17 PHYVAL: 0x00008208
dump_netinfo: id=18 PHYVAL: 0x00007800
dump_netinfo: id=19 PHYVAL: 0x00000000
dump_netinfo: id=20 PHYVAL: 0x00000000
dump_netinfo: id=21 PHYVAL: 0x00001f00
dump_netinfo: id=22 PHYVAL: 0x00000001
dump_netinfo: id=23 PHYVAL: 0x00000001
dump_netinfo: id=24 PHYVAL: 0x0000cce0
dump_netinfo: id=25 PHYVAL: 0x00000000
dump_netinfo: id=26 PHYVAL: 0x00000000
dump_netinfo: id=27 PHYVAL: 0x00000000
dump_netinfo: id=28 PHYVAL: 0x00000000
dump_netinfo: id=29 PHYVAL: 0x00000000
dump_netinfo: id=30 PHYVAL: 0x00000000
dump_netinfo: id=31 PHYVAL: 0x00000000
stm32_macaddress: eth0 MAC: 00:e0:de:ad:be:ef
dump_netinfo: id=0 PHYVAL: 0x00003100
dump_netinfo: id=1 PHYVAL: 0x0000786d
dump_netinfo: id=2 PHYVAL: 0x00000181
dump_netinfo: id=3 PHYVAL: 0x0000b8a0
dump_netinfo: id=4 PHYVAL: 0x000001e1
dump_netinfo: id=5 PHYVAL: 0x00004de1
dump_netinfo: id=6 PHYVAL: 0x00000001
dump_netinfo: id=7 PHYVAL: 0x00000000
dump_netinfo: id=8 PHYVAL: 0x00000000
dump_netinfo: id=9 PHYVAL: 0x00000000
dump_netinfo: id=10 PHYVAL: 0x00000000
dump_netinfo: id=11 PHYVAL: 0x00000000
dump_netinfo: id=12 PHYVAL: 0x00000000
dump_netinfo: id=13 PHYVAL: 0x00000000
dump_netinfo: id=14 PHYVAL: 0x00000000
dump_netinfo: id=15 PHYVAL: 0x00000000
dump_netinfo: id=16 PHYVAL: 0x00000514
dump_netinfo: id=17 PHYVAL: 0x00008208
dump_netinfo: id=18 PHYVAL: 0x00007800
dump_netinfo: id=19 PHYVAL: 0x00000000
dump_netinfo: id=20 PHYVAL: 0x00000000
dump_netinfo: id=21 PHYVAL: 0x00001f00
dump_netinfo: id=22 PHYVAL: 0x00000000
dump_netinfo: id=23 PHYVAL: 0x00000000
dump_netinfo: id=24 PHYVAL: 0x0000cce0
dump_netinfo: id=25 PHYVAL: 0x00000000
dump_netinfo: id=26 PHYVAL: 0x00000000
dump_netinfo: id=27 PHYVAL: 0x00000000
dump_netinfo: id=28 PHYVAL: 0x00000000
dump_netinfo: id=29 PHYVAL: 0x00000000
dump_netinfo: id=30 PHYVAL: 0x00000000
dump_netinfo: id=31 PHYVAL: 0x00000000
netdev_ifrioctl: cmd: 1796
netdev_ifrioctl: cmd: 1800
nsh_ttelnetd_daemon: Accepting connections on port 23
elnetstart: Starting the Telnet daemon

NuttShell (NSH)
nsh> ping 192.168.150.1
stm32_txavail: ifup: 1
uip_callbackexecute: Call event=80138e1 with flags=0010
ping_interrupt: flags: 0010
ping_interrupt: Send ECHO request: seqno=1
uip_icmpsend: Outgoing ICMP packet length: 84 (84)
uip_arp_out: ARP request for IP 196a8c0
stm32_transmit: d_len: 42 d_buf: 2000290c txhead: 200004cc tdes0: 00100000
stm32_transmit: txhead: 200004dc txtail: 200004cc inflight: 1
uip_ping: Start time: 0x00000f3d seqno: 1
stm32_freeframe: txhead: 200004dc txtail: 200004cc inflight: 1
stm32_freeframe: txtail: 200004cc tdes0: 70100000 tdes2: 2000290c tdes3: 200004dc
uip_callbackexecute: Call event=80138e1 with flags=0010
ping_interrupt: flags: 0010
uip_callbackexecute: Call event=80138e1 with flags=0010
ping_interrupt: flags: 0010
uip_callbackexecute: Call event=80138e1 with flags=0010
ping_interrupt: flags: 0010
ping_interrupt: Ping timeout
ping_interrupt: Resuming
uip_ping: Return error=110
stm32_txavail: ifup: 1
uip_callbackexecute: Call event=80138e1 with flags=0010
ping_interrupt: flags: 0010
ping_interrupt: Send ECHO request: seqno=2
uip_icmpsend: Outgoing ICMP packet length: 84 (84)
uip_arp_out: ARP request for IP 196a8c0
stm32_transmit: d_len: 42 d_buf: 20002d0c txhead: 200004dc tdes0: 00100000
stm32_transmit: txhead: 200004ec txtail: 200004dc inflight: 1
uip_ping: Start time: 0x00000fe3 seqno: 2
stm32_freeframe: txhead: 200004ec txtail: 200004dc inflight: 1
stm32_freeframe: txtail: 200004dc tdes0: 70100000 tdes2: 20002d0c tdes3: 200004ec
uip_callbackexecute: Call event=80138e1 with flags=0010
ping_interrupt: flags: 0010
uip_callbackexecute: Call event=80138e1 with flags=0010
ping_interrupt: flags: 0010
ping_interrupt: Ping timeout
ping_interrupt: Resuming
uip_ping: Return error=110
stm32_txavail: ifup: 1
uip_callbackexecute: Call event=80138e1 with flags=0010
ping_interrupt: flags: 0010
ping_interrupt: Send ECHO request: seqno=3
uip_icmpsend: Outgoing ICMP packet length: 84 (84)
uip_arp_out: ARP request for IP 196a8c0
stm32_transmit: d_len: 42 d_buf: 2000250c txhead: 200004ec tdes0: 00100000
stm32_transmit: txhead: 200004fc txtail: 200004ec inflight: 1
uip_ping: Start time: 0x00001048 seqno: 3
stm32_freeframe: txhead: 200004fc txtail: 200004ec inflight: 1
stm32_freeframe: txtail: 200004ec tdes0: 70100000 tdes2: 2000250c tdes3: 200004fc
uip_callbackexecute: Call event=80138e1 with flags=0010
ping_interrupt: flags: 0010
uip_callbackexecute: Call event=80138e1 with flags=0010
ping_interrupt: flags: 0010
ping_interrupt: Ping timeout
ping_interrupt: Resuming
uip_ping: Return error=110
stm32_txavail: ifup: 1
uip_callbackexecute: Call event=80138e1 with flags=0010
ping_interrupt: flags: 0010
ping_interrupt: Send ECHO request: seqno=4
uip_icmpsend: Outgoing ICMP packet length: 84 (84)
uip_arp_out: ARP request for IP 196a8c0
stm32_transmit: d_len: 42 d_buf: 2000350c txhead: 200004fc tdes0: 00100000
stm32_transmit: txhead: 200004cc txtail: 200004fc inflight: 1
uip_ping: Start time: 0x000010ad seqno: 4
stm32_freeframe: txhead: 200004cc txtail: 200004fc inflight: 1
stm32_freeframe: txtail: 200004fc tdes0: 70100000 tdes2: 2000350c tdes3: 200004cc
uip_callbackexecute: Call event=80138e1 with flags=0010
ping_interrupt: flags: 0010
uip_callbackexecute: Call event=80138e1 with flags=0010
ping_interrupt: flags: 0010
ping_interrupt: Ping timeout
ping_interrupt: Resuming
uip_ping: Return error=110
stm32_txavail: ifup: 1
uip_callbackexecute: Call event=80138e1 with flags=0010
ping_interrupt: flags: 0010
ping_interrupt: Send ECHO request: seqno=5
uip_icmpsend: Outgoing ICMP packet length: 84 (84)
uip_arp_out: ARP request for IP 196a8c0
stm32_transmit: d_len: 42 d_buf: 2000310c txhead: 200004cc tdes0: 70100000
stm32_transmit: txhead: 200004dc txtail: 200004cc inflight: 1
uip_ping: Start time: 0x00001112 seqno: 5
stm32_freeframe: txhead: 200004dc txtail: 200004cc inflight: 1
stm32_freeframe: txtail: 200004cc tdes0: 70100000 tdes2: 2000310c tdes3: 200004dc
uip_callbackexecute: Call event=80138e1 with flags=0010
ping_interrupt: flags: 0010
uip_callbackexecute: Call event=80138e1 with flags=0010
ping_interrupt: flags: 0010
ping_interrupt: Ping timeout
ping_interrupt: Resuming
uip_ping: Return error=110
stm32_txavail: ifup: 1
uip_callbackexecute: Call event=80138e1 with flags=0010
ping_interrupt: flags: 0010
ping_interrupt: Send ECHO request: seqno=6
uip_icmpsend: Outgoing ICMP packet length: 84 (84)
uip_arp_out: ARP request for IP 196a8c0
stm32_transmit: d_len: 42 d_buf: 20002d0c txhead: 200004dc tdes0: 70100000
stm32_transmit: txhead: 200004ec txtail: 200004dc inflight: 1
uip_ping: Start time: 0x00001177 seqno: 6
stm32_freeframe: txhead: 200004ec txtail: 200004dc inflight: 1
stm32_freeframe: txtail: 200004dc tdes0: 70100000 tdes2: 20002d0c tdes3: 200004ec
uip_callbackexecute: Call event=80138e1 with flags=0010
ping_interrupt: flags: 0010
uip_callbackexecute: Call event=80138e1 with flags=0010
ping_interrupt: flags: 0010
ping_interrupt: Ping timeout
ping_interrupt: Resuming
uip_ping: Return error=110
stm32_txavail: ifup: 1
uip_callbackexecute: Call event=80138e1 with flags=0010
ping_interrupt: flags: 0010
ping_interrupt: Send ECHO request: seqno=7
uip_icmpsend: Outgoing ICMP packet length: 84 (84)
uip_arp_out: ARP request for IP 196a8c0
stm32_transmit: d_len: 42 d_buf: 2000250c txhead: 200004ec tdes0: 70100000
stm32_transmit: txhead: 200004fc txtail: 200004ec inflight: 1
uip_ping: Start time: 0x000011dc seqno: 7
stm32_freeframe: txhead: 200004fc txtail: 200004ec inflight: 1
stm32_freeframe: txtail: 200004ec tdes0: 70100000 tdes2: 2000250c tdes3: 200004fc
uip_callbackexecute: Call event=80138e1 with flags=0010
ping_interrupt: flags: 0010
uip_callbackexecute: Call event=80138e1 with flags=0010
ping_interrupt: flags: 0010
ping_interrupt: Ping timeout
ping_interrupt: Resuming
uip_ping: Return error=110
stm32_txavail: ifup: 1
uip_callbackexecute: Call event=80138e1 with flags=0010
ping_interrupt: flags: 0010
ping_interrupt: Send ECHO request: seqno=8
uip_icmpsend: Outgoing ICMP packet length: 84 (84)
uip_arp_out: ARP request for IP 196a8c0
stm32_transmit: d_len: 42 d_buf: 2000350c txhead: 200004fc tdes0: 70100000
stm32_transmit: txhead: 200004cc txtail: 200004fc inflight: 1
uip_ping: Start time: 0x00001241 seqno: 8
stm32_freeframe: txhead: 200004cc txtail: 200004fc inflight: 1
stm32_freeframe: txtail: 200004fc tdes0: 70100000 tdes2: 2000350c tdes3: 200004cc
uip_callbackexecute: Call event=80138e1 with flags=0010
ping_interrupt: flags: 0010
uip_callbackexecute: Call event=80138e1 with flags=0010
ping_interrupt: flags: 0010
ping_interrupt: Ping timeout
ping_interrupt: Resuming
uip_ping: Return error=110
stm32_txavail: ifup: 1
uip_callbackexecute: Call event=80138e1 with flags=0010
ping_interrupt: flags: 0010
ping_interrupt: Send ECHO request: seqno=9
uip_icmpsend: Outgoing ICMP packet length: 84 (84)
uip_arp_out: ARP request for IP 196a8c0
stm32_transmit: d_len: 42 d_buf: 2000310c txhead: 200004cc tdes0: 70100000
stm32_transmit: txhead: 200004dc txtail: 200004cc inflight: 1
uip_ping: Start time: 0x000012a6 seqno: 9
stm32_freeframe: txhead: 200004dc txtail: 200004cc inflight: 1
stm32_freeframe: txtail: 200004cc tdes0: 70100000 tdes2: 2000310c tdes3: 200004dc
uip_callbackexecute: Call event=80138e1 with flags=0010
ping_interrupt: flags: 0010
uip_callbackexecute: Call event=80138e1 with flags=0010
ping_interrupt: flags: 0010
ping_interrupt: Ping timeout
ping_interrupt: Resuming
uip_ping: Return error=110
stm32_txavail: ifup: 1
uip_callbackexecute: Call event=80138e1 with flags=0010
ping_interrupt: flags: 0010
ping_interrupt: Send ECHO request: seqno=10
uip_icmpsend: Outgoing ICMP packet length: 84 (84)
uip_arp_out: ARP request for IP 196a8c0
stm32_transmit: d_len: 42 d_buf: 20002d0c txhead: 200004dc tdes0: 70100000
stm32_transmit: txhead: 200004ec txtail: 200004dc inflight: 1
uip_ping: Start time: 0x0000130b seqno: 10
stm32_freeframe: txhead: 200004ec txtail: 200004dc inflight: 1
stm32_freeframe: txtail: 200004dc tdes0: 70100000 tdes2: 20002d0c tdes3: 200004ec
uip_callbackexecute: Call event=80138e1 with flags=0010
ping_interrupt: flags: 0010
uip_callbackexecute: Call event=80138e1 with flags=0010
ping_interrupt: flags: 0010
ping_interrupt: Ping timeout
ping_interrupt: Resuming
uip_ping: Return error=110
PING 192.168.150.1 56 bytes of data
10 packets transmitted, 0 received, 100% packet loss, time 10750 ms

darcy
Post by Gregory N
Hi, Shenzhou
You said that ping does not work. What kind of debug output do you see when you do the ping. What kind of error messages do you see when you ping?
CONFIG_DEBUG=y
CONFIG_DEBUG_VERBOSE=y
CONFIG_DEBUG_NET=y
CONFIG_STM32_ETHMAC_REGDEBUG=y Will show every register access.
Greg
Gregory N
2012-08-29 18:38:49 UTC
Permalink
Hi, Darcy,
Post by darcygong
nsh> ping 192.168.150.1
First, stm32_txavail is called from uip_ping() in nuttx/net/uip/uip_icmpping.c the ping application has something to send.
Post by darcygong
stm32_txavail: ifup: 1
uip_callbackexecute: Call event=80138e1 with flags=0010
ping_interrupt: flags: 0010
ping_interrupt: Send ECHO request: seqno=1
uip_icmpsend: Outgoing ICMP packet length: 84 (84)
uip_arp_out: ARP request for IP 196a8c0
stm32_transmit: d_len: 42 d_buf: 2000290c txhead: 200004cc tdes0: 00100000
stm32_transmit: txhead: 200004dc txtail: 200004cc inflight: 1
uip_ping: Start time: 0x00000f3d seqno: 1
stm32_freeframe: txhead: 200004dc txtail: 200004cc inflight: 1
stm32_freeframe: txtail: 200004cc tdes0: 70100000 tdes2: 2000290c tdes3: 200004dc
... additional polls removed ...
uip_callbackexecute: Call event=80138e1 with flags=0010
ping_interrupt: flags: 0010
ping_interrupt: Ping timeout
ping_interrupt: Resuming
uip_ping: Return error=110
The above sequence repeats 9 more times for the other ECHO requests. What could cause this:

1. Perhaps the ARP request did not make it onto the network? There could, for example, be a problem with the output pin configuration so that the Ethernet driver or with the PHY so that the output ECHO request is not being placed on the wire?

You can find out for use using a network sniffer like WireShark. If you see the ECHO request packet coming out of the STM32 on the wire, then the packet was transmitted okay. With WireShark, you see a packet like:

Source: 00:e0:de:ad:be:ef
Destination: Broadcast
Protocol: ARP
Info: Who has 192.168.150.1? Tell 192.168.150.56

2. Perhaps the IP address is bad? Perhaps 192.168.150.1 is not reachable from the target? Again, I would use WireShark. If the ARP request for "Who is 192.168.150.1" appears on the wire correctly, but there is no response. Then the problem is not with the STM32 but with the IP address or the network or remote host configuration.

3. Is the host machine at 192.168.150.1 a Windows machine? I believe that by default Windows blocks ECHO requests. But I think it should honor ARP requests. I sometimes have to modify the Windows firewall in order to get a ping response.

4. A final possibility is that the ARP request for "Who is 192.168.150.1" is okay AND the response appears properly on the wire too. In that case, there is something wrong with the reception logic on the STM32. Again, pin configuration or PHY configuration would be the most likely candidates.

Using WireShark so narrow the problem down a lot.

Greg
Max Holtzberg
2012-08-29 23:37:51 UTC
Permalink
Post by darcygong
Post by Max Holtzberg
Post by darcygong
I shenzhou iv stm32f107 a development board, board dm9161 Ethernet phy chip RMII work mode.Configured and compiled, nsh shell work, eth0 not found the device in the /dev/ (nsh shell), also can not ping.Advice on how to determine the problems and solutions. Thank!
tips are as follows
NuttShell (NSH)
nsh> ls dev
console
null
ttyS0
nsh> ADE
netdev_register: Registered MAC: 00:00:00:00:00:00 as dev: eth0
netdev_ifrioctl: cmd:stm32_ethconfig: Reset the Ethernet block
stm32_ethconfig: Initialize the PHY
1803
netdev_ifrioctl: cmd: 1794
stm32_ifdown: Taking the network down
stm32_ifup: Bringing up: 192.168.150.56
stm32_phyinit: PHYVAL: 385 | 181
stm32_phyinit: Find PHY: DM9161AEP
stm32_phstm32_ethconfig: Initialize the MAC and DMA
stm32_ethconfig: Enable normal operation
stm32_macaddress: eth0 MAC: 00:e0:de:ad:be:ef
yinit: Duplex: FULL Stelnetd_daemon: Accepting connections on port 23
peed: 100 MBps
netdev_ifrioctl: cmd: 1796
netdev_ifrioctl: cmd: 1800
nsh_telnetstart: Starting the Telnet daemon
NuttShell (NSH)
nsh>
Hi,
I also tried to get Ethernet working on a stm32f107.
Do you get "stm32_interrupt: Abormal event(s): 00008080" too?
(Maybe with CONFIG_DEBUG_VERBOSE=y)
I had no time yet to investigate that further...
Max
Hi, Max.
I open the debug, but did not find this error message you said. The development board you are now able to work?
Unfortunately not.

Max
darcygong
2012-08-30 08:06:45 UTC
Permalink
Post by Max Holtzberg
Post by darcygong
Post by Max Holtzberg
Post by darcygong
I shenzhou iv stm32f107 a development board, board dm9161 Ethernet phy chip RMII work mode.Configured and compiled, nsh shell work, eth0 not found the device in the /dev/ (nsh shell), also can not ping.Advice on how to determine the problems and solutions. Thank!
tips are as follows
NuttShell (NSH)
nsh> ls dev
console
null
ttyS0
nsh> ADE
netdev_register: Registered MAC: 00:00:00:00:00:00 as dev: eth0
netdev_ifrioctl: cmd:stm32_ethconfig: Reset the Ethernet block
stm32_ethconfig: Initialize the PHY
1803
netdev_ifrioctl: cmd: 1794
stm32_ifdown: Taking the network down
stm32_ifup: Bringing up: 192.168.150.56
stm32_phyinit: PHYVAL: 385 | 181
stm32_phyinit: Find PHY: DM9161AEP
stm32_phstm32_ethconfig: Initialize the MAC and DMA
stm32_ethconfig: Enable normal operation
stm32_macaddress: eth0 MAC: 00:e0:de:ad:be:ef
yinit: Duplex: FULL Stelnetd_daemon: Accepting connections on port 23
peed: 100 MBps
netdev_ifrioctl: cmd: 1796
netdev_ifrioctl: cmd: 1800
nsh_telnetstart: Starting the Telnet daemon
NuttShell (NSH)
nsh>
Hi,
I also tried to get Ethernet working on a stm32f107.
Do you get "stm32_interrupt: Abormal event(s): 00008080" too?
(Maybe with CONFIG_DEBUG_VERBOSE=y)
I had no time yet to investigate that further...
Max
Hi, Max.
I open the debug, but did not find this error message you said. The development board you are now able to work?
Unfortunately not.
Max
hi Max,
I give Grep express the the three development board, which is a STM32F107 + DP83848C ;-).
Electronic engineers in China, like using low-cost Ethernet PHY chip, such as DM9161 LAN8720.Others such as STM32F103 the + enc28j60 or stm32f103 + dm9000 is also very common.DP83848C the program more expensive, with fewer people.

darcy
Gregory N
2012-09-23 15:16:39 UTC
Permalink
Hi, Max,
Post by Max Holtzberg
I also tried to get Ethernet working on a stm32f107.
Do you get "stm32_interrupt: Abormal event(s): 00008080" too?
(Maybe with CONFIG_DEBUG_VERBOSE=y)
I had no time yet to investigate that further...
I am now working with the Shenzhou STM32F107 board with Darcy. We have a configuration (based largely on your Olimex configuration) and almost have Ethernet working. But now we are seeing the same problem that you were seeing using the DM9161 PHY:

stm32_interrupt: Abormal event(s): 00008080

This happens frequently. When pinging from the target, this causes about 80% packet loss or more. When pinging from the host, it causes "No route to host" or "Connectin time out"

The important bit of information is bit 7:

"Bit 7 RBUS: Receive buffer unavailable status: This bit indicates that the next descriptor in the receive list is owned by the host and cannot be acquired by the DMA. Receive process is suspended. To resume processing receive descriptors, the host should change the ownership of the descriptor and issue a Receive Poll Demand command. If no Receive Poll Demand is issued, receive process resumes when the next recognized incoming frame is received. ETH_DMASR [7] is set only when the previous receive descriptor was owned by the DMA."

I have debug output that shows the following sequence of events when I ping from target:

1. Seven ECHO requests were sent from the target and nothing was received (Wireshark was not running, but I am pretty sure that the ECHO requests were sent and responded to).

2. On the 8th ECHO request, 8 ECHO responses are received back-to-back. I have to assume that these were already in DMA memory, but there was no interrupt event prior to this to inform the firmaware that the receive packet is available.

3. Then 2 more ECHO requests were sent from target and nothing was received. But then the following abnormal errors were reported:

stm32_interrupt: Abormal event(s): 000180c0
stm32_interrupt: Abormal event(s): 00008080
stm32_interrupt: Abormal event(s): 00008080

The second two are your old friends. But the first also has bit 6 set meaning that a receive interrupt is pending (but no interrupt was taken).

I don't understand the full cause of the 0008080 problem but I don't believe that it is a PHY problem. I believe that it has to do with receive interrupts not be taken. I believe that we happen to process some receive packets when an interrupt happens to occur with the receive interrupt pending, but I do not believe that the receive event is generating an interrupt. As a result, eventually, you run out of buffers and the "Receive Buffer Unavailable" interrupt ocurrs. At least that is my theory.

Do you have any insight? I will continue to look at this.

Greg
Max Holtzberg
2012-09-23 22:00:57 UTC
Permalink
Post by Gregory N
Hi, Max,
Post by Max Holtzberg
I also tried to get Ethernet working on a stm32f107.
Do you get "stm32_interrupt: Abormal event(s): 00008080" too?
(Maybe with CONFIG_DEBUG_VERBOSE=y)
I had no time yet to investigate that further...
stm32_interrupt: Abormal event(s): 00008080
This happens frequently. When pinging from the target, this causes about 80% packet loss or more. When pinging from the host, it causes "No route to host" or "Connectin time out"
"Bit 7 RBUS: Receive buffer unavailable status: This bit indicates that the next descriptor in the receive list is owned by the host and cannot be acquired by the DMA. Receive process is suspended. To resume processing receive descriptors, the host should change the ownership of the descriptor and issue a Receive Poll Demand command. If no Receive Poll Demand is issued, receive process resumes when the next recognized incoming frame is received. ETH_DMASR [7] is set only when the previous receive descriptor was owned by the DMA."
1. Seven ECHO requests were sent from the target and nothing was received (Wireshark was not running, but I am pretty sure that the ECHO requests were sent and responded to).
2. On the 8th ECHO request, 8 ECHO responses are received back-to-back. I have to assume that these were already in DMA memory, but there was no interrupt event prior to this to inform the firmaware that the receive packet is available.
stm32_interrupt: Abormal event(s): 000180c0
stm32_interrupt: Abormal event(s): 00008080
stm32_interrupt: Abormal event(s): 00008080
The second two are your old friends. But the first also has bit 6 set meaning that a receive interrupt is pending (but no interrupt was taken).
I don't understand the full cause of the 0008080 problem but I don't believe that it is a PHY problem. I believe that it has to do with receive interrupts not be taken. I believe that we happen to process some receive packets when an interrupt happens to occur with the receive interrupt pending, but I do not believe that the receive event is generating an interrupt. As a result, eventually, you run out of buffers and the "Receive Buffer Unavailable" interrupt ocurrs. At least that is my theory.
Do you have any insight? I will continue to look at this.
Greg
Hi Greg,

I had no more ideas how to fix that and stopped investigating, but I'm
still interested to get it working.
Have you tried to stop the program with an infinity loop in the
applications main? In my case no abnormal interrupts occurred and ping
worked fine.
I'm not sure if remember correctly but:
I "infinity loop"ed down to find where abnormal interrupts start to
occur and found out that it was after the context switch generated
from the uip_lockedwait.

That's all I have. Tomorrow I will check it again with the stm32p107
board.

Max
Gregory N
2012-09-23 22:33:30 UTC
Permalink
Hi, Max,
Post by Max Holtzberg
I had no more ideas how to fix that and stopped investigating, but I'm
still interested to get it working.
Have you tried to stop the program with an infinity loop in the
applications main? In my case no abnormal interrupts occurred and ping
worked fine.
I "infinity loop"ed down to find where abnormal interrupts start to
occur and found out that it was after the context switch generated
from the uip_lockedwait.
That's all I have. Tomorrow I will check it again with the stm32p107
board.
From what I saw, it seems like the root cause of the problem is simply that there are no interrupts to indicate that Rx data has been received (although Tx done interrupts seem occur normally). The Buffered Rx data accumulates until we run out of buffer space,then the 0008080 abnormal event occurs.
This might tie into context switching somehow, maybe through some sneak logic. But studying the context switching does not sound like an easy approach to debugging the problem.

Using the same code, the F2 and F4 Ethernet does not have any problem like this. This problem is unique to the F107. The F107 Ethernet IP is very similar to the F2/F4 but not identical.

I'll be looking into this later this week too. Between the three of us, we should get it solved (I bet the solution is simple).

You will notice a few differences in the Olimex STM32-P107 configuration. For example, I moved your custom clock configuration to make it the "standard" clock configuratiom for the Connectivity Line.

Greg
Gregory N
2012-09-24 15:31:48 UTC
Permalink
Hi, Max, Darcy,

I think I have fixed the problem. I have a few things to clean up, I'll tell you when it is all checked in.
Post by Max Holtzberg
Post by Max Holtzberg
Have you tried to stop the program with an infinity loop in the
applications main? In my case no abnormal interrupts occurred and ping
worked fine.
I "infinity loop"ed down to find where abnormal interrupts start to
occur and found out that it was after the context switch generated
from the uip_lockedwait.
That's all I have. Tomorrow I will check it again with the stm32p107
board.
When you wait in uip_lockedwait(), then the IDLE loop in arch/arm/src/stm32/stm32_idle runs. It puts the system into SLEEP mode by executing

asm("wfi");

But, unfortunately, there is an errata in the F107 chip:

"2.17.11 Ethernet DMA not working after WFI/WFE instruction

Description
If a WFI/WFE instruction is executed to put the system in sleep mode while the Ethernet MAC master clock on the AHB bus matrix is ON and all remaining masters clocks are OFF, the Ethernet DMA will be not able to perform any AHB master accesses during sleep mode.

Workaround
Enable DMA1 or DMA2 clocks in the RCC_AHBENR register before executing the WFI/WFE instruction."

If you comment out the 'asm("wfi")' statement in stm32_idle(), then Ethernet pings seems to work fine. More testing is needed.

I have also corrected an alignment problem that has not been checked in. That may or may not be required as well.
Post by Max Holtzberg
From what I saw, it seems like the root cause of the problem is simply that there are no interrupts to indicate that Rx data has been received (although Tx done interrupts seem occur normally). The Buffered Rx data accumulates until we run out of buffer space,then the 0008080 abnormal event occurs.
Well, that is true too.. When the DMA is stopped, the Rx interrupts are stopped too.
Post by Max Holtzberg
This might tie into context switching somehow, maybe through some sneak logic. But studying the context switching does not sound like an easy approach to debugging the problem.
Indeed! The classic sneak logic path.
Post by Max Holtzberg
Using the same code, the F2 and F4 Ethernet does not have any problem like this. This problem is unique to the F107. The F107 Ethernet IP is very similar to the F2/F4 but not identical.
Because the F2/F4 do not have the errata.

And this probabaly explains with the driver that Darcy looked at with RT-Thread does not have the problem. It probably does not go into SLEEP mode while Ethernet is transferring data.

Greg
Max Holtzberg
2012-09-24 15:49:53 UTC
Permalink
Post by Gregory N
Hi, Max, Darcy,
I think I have fixed the problem. I have a few things to clean up, I'll tell you when it is all checked in.
Post by Max Holtzberg
Post by Max Holtzberg
Have you tried to stop the program with an infinity loop in the
applications main? In my case no abnormal interrupts occurred and ping
worked fine.
I "infinity loop"ed down to find where abnormal interrupts start to
occur and found out that it was after the context switch generated
from the uip_lockedwait.
That's all I have. Tomorrow I will check it again with the stm32p107
board.
When you wait in uip_lockedwait(), then the IDLE loop in arch/arm/src/stm32/stm32_idle runs. It puts the system into SLEEP mode by executing
asm("wfi");
"2.17.11 Ethernet DMA not working after WFI/WFE instruction
Description
If a WFI/WFE instruction is executed to put the system in sleep mode while the Ethernet MAC master clock on the AHB bus matrix is ON and all remaining masters clocks are OFF, the Ethernet DMA will be not able to perform any AHB master accesses during sleep mode.
Workaround
Enable DMA1 or DMA2 clocks in the RCC_AHBENR register before executing the WFI/WFE instruction."
If you comment out the 'asm("wfi")' statement in stm32_idle(), then Ethernet pings seems to work fine. More testing is needed.
Unfortunately, I looked for that instruction found it, and came to the
conclusion that it is not called in that context. Now I wonder why I
did not ask for that. However Nice that it is fixed now.
Thank you!!!
Post by Gregory N
I have also corrected an alignment problem that has not been checked in. That may or may not be required as well.
Post by Max Holtzberg
From what I saw, it seems like the root cause of the problem is simply that there are no interrupts to indicate that Rx data has been received (although Tx done interrupts seem occur normally). The Buffered Rx data accumulates until we run out of buffer space,then the 0008080 abnormal event occurs.
Well, that is true too.. When the DMA is stopped, the Rx interrupts are stopped too.
Post by Max Holtzberg
This might tie into context switching somehow, maybe through some sneak logic. But studying the context switching does not sound like an easy approach to debugging the problem.
Indeed! The classic sneak logic path.
Post by Max Holtzberg
Using the same code, the F2 and F4 Ethernet does not have any problem like this. This problem is unique to the F107. The F107 Ethernet IP is very similar to the F2/F4 but not identical.
Because the F2/F4 do not have the errata.
And this probabaly explains with the driver that Darcy looked at with RT-Thread does not have the problem. It probably does not go into SLEEP mode while Ethernet is transferring data.
Greg
Gregory Nutt
2012-09-24 15:53:26 UTC
Permalink
Max, Darcy,

The fix is checked in and appears to work.  I now get 0% packet loss in pings (other than the first one).

Greg

Gong Darcy
2012-09-24 00:48:42 UTC
Permalink
hi Greg and Max,

Have you looked at the ST STM32F10x RM0008 Reference manual yet?
The English version of section 28.6.9 section mentioned: (I see section
27.6.9 of the Chinese translation edition)
1) DMASR [7] interrupt occurs, may produce one or more DMASR [6] of the
interrupt is not processed
2) F107 DMA interrupt. If both multiple interrupt. Processed an interrupt
will then appear next. Also need to be cleared.

I suspect that part of the reason. I will do the checking. However, I am
new to the microcontroller. So the best you also check.

Darcy.

FORM RM0008 Reference manual (28.6.9 section):

28.6.9 DMA interrupts
Interrupts can be generated as a result of various events. The ETH_DMASR
register
contains all the bits that might cause an interrupt. The ETH_DMAIER
register contains an
enable bit for each of the events that can cause an interrupt.
There are two groups of interrupts, Normal and Abnormal, as described in
the
ETH_DMASR register. Interrupts are cleared by writing a 1 to the
corresponding bit position.
When all the enabled interrupts within a group are cleared, the
corresponding summary bit
is cleared. If the MAC core is the cause for assertion of the interrupt,
then any of the TSTS
or PMTS bits in the ETH_DMASR register is set high.
Interrupts are not queued and if the interrupt event occurs before the
driver has responded
to it, no additional interrupts are generated. For example, the Receive
Interrupt bit
(ETH_DMASR register [6]) indicates that one or more frames were transferred
to the
STM32F107xx buffer. The driver must scan all descriptors, from the last
recorded position to
the first one owned by the DMA.
An interrupt is generated only once for simultaneous, multiple events. The
driver must scan
the ETH_DMASR register for the cause of the interrupt. The interrupt is not
generated again
unless a new interrupting event occurs, after the driver has cleared the
appropriate bit in the
ETH_DMASR register. For example, the controller generates a Receive
interrupt
(ETH_DMASR register[6]) and the driver begins reading the ETH_DMASR
register. Next,
receive buffer unavailable (ETH_DMASR register[7]) occurs. The driver
clears the Receive
interrupt. Even then, a new interrupt is generated, due to the active or
pending Receive
buffer unavailable interrupt.
Post by Gregory N
**
Hi, Max,
Post by Max Holtzberg
I also tried to get Ethernet working on a stm32f107.
Do you get "stm32_interrupt: Abormal event(s): 00008080" too?
(Maybe with CONFIG_DEBUG_VERBOSE=y)
I had no time yet to investigate that further...
I am now working with the Shenzhou STM32F107 board with Darcy. We have a
configuration (based largely on your Olimex configuration) and almost have
Ethernet working. But now we are seeing the same problem that you were
stm32_interrupt: Abormal event(s): 00008080
This happens frequently. When pinging from the target, this causes about
80% packet loss or more. When pinging from the host, it causes "No route to
host" or "Connectin time out"
"Bit 7 RBUS: Receive buffer unavailable status: This bit indicates that
the next descriptor in the receive list is owned by the host and cannot be
acquired by the DMA. Receive process is suspended. To resume processing
receive descriptors, the host should change the ownership of the descriptor
and issue a Receive Poll Demand command. If no Receive Poll Demand is
issued, receive process resumes when the next recognized incoming frame is
received. ETH_DMASR [7] is set only when the previous receive descriptor
was owned by the DMA."
1. Seven ECHO requests were sent from the target and nothing was received
(Wireshark was not running, but I am pretty sure that the ECHO requests
were sent and responded to).
2. On the 8th ECHO request, 8 ECHO responses are received back-to-back. I
have to assume that these were already in DMA memory, but there was no
interrupt event prior to this to inform the firmaware that the receive
packet is available.
3. Then 2 more ECHO requests were sent from target and nothing was
stm32_interrupt: Abormal event(s): 000180c0
stm32_interrupt: Abormal event(s): 00008080
stm32_interrupt: Abormal event(s): 00008080
The second two are your old friends. But the first also has bit 6 set
meaning that a receive interrupt is pending (but no interrupt was taken).
I don't understand the full cause of the 0008080 problem but I don't
believe that it is a PHY problem. I believe that it has to do with receive
interrupts not be taken. I believe that we happen to process some receive
packets when an interrupt happens to occur with the receive interrupt
pending, but I do not believe that the receive event is generating an
interrupt. As a result, eventually, you run out of buffers and the "Receive
Buffer Unavailable" interrupt ocurrs. At least that is my theory.
Do you have any insight? I will continue to look at this.
Greg
Gong Darcy
2012-09-24 08:42:41 UTC
Permalink
hi Greg and Max,

I compare the rt-thread stm32f107 code (can work).
Found that the differences in processing the interrupt function.
stm32_interrupt and ETH_IRQHandler (rt-thread)
ETH_IRQHandler for ETH_DMA_IT_RBU (DMASR [7]) to do the processing.
Reset This bit before. Running ETH_ResumeDMAReception () function.
This function is executed only ETH-> DMARPDR = 0;
Also detected ETH_DMA_IT_TBU (DMASR [2]) is set ETH -> DMATPDR = 0;
I will modify the code under test.

darcy

==============================================================
/**
* @brief Clears the ETHERNET's DMA IT pending bit.
* @param ETH_DMA_IT: specifies the interrupt pending bit to clear.
* This parameter can be any combination of the following values:
* @arg ETH_DMA_IT_NIS : Normal interrupt summary
* @arg ETH_DMA_IT_AIS : Abnormal interrupt summary
* @arg ETH_DMA_IT_ER : Early receive interrupt
* @arg ETH_DMA_IT_FBE : Fatal bus error interrupt
* @arg ETH_DMA_IT_ETI : Early transmit interrupt
* @arg ETH_DMA_IT_RWT : Receive watchdog timeout interrupt
* @arg ETH_DMA_IT_RPS : Receive process stopped interrupt
* @arg ETH_DMA_IT_RBU : Receive buffer unavailable interrupt
* @arg ETH_DMA_IT_R : Receive interrupt
* @arg ETH_DMA_IT_TU : Transmit Underflow interrupt
* @arg ETH_DMA_IT_RO : Receive Overflow interrupt
* @arg ETH_DMA_IT_TJT : Transmit jabber timeout interrupt
* @arg ETH_DMA_IT_TBU : Transmit buffer unavailable interrupt
* @arg ETH_DMA_IT_TPS : Transmit process stopped interrupt
* @arg ETH_DMA_IT_T : Transmit interrupt
* @retval None
*/

/**
* @brief Resumes the DMA Transmission by writing to the DmaTxPollDemand
register
* (the data written could be anything). This forces the DMA to resume
transmission.
* @param None
* @retval None.
*/
void ETH_ResumeDMATransmission(void)
{
ETH->DMATPDR = 0;
}

/**
* @brief Resumes the DMA Transmission by writing to the DmaRxPollDemand
register
* (the data written could be anything). This forces the DMA to resume
reception.
* @param None
* @retval None.
*/
void ETH_ResumeDMAReception(void)
{
ETH->DMARPDR = 0;
}

/* interrupt service routine for ETH */
void ETH_IRQHandler(void)
{
rt_uint32_t status;

/* enter interrupt */
rt_interrupt_enter();

/* get DMA IT status */
status = ETH->DMASR;

if ( (status & ETH_DMA_IT_R) != (u32)RESET ) /* packet receiption */
{
/* a frame has been received */
eth_device_ready(&(stm32_eth_device.parent));

ETH_DMAClearITPendingBit(ETH_DMA_IT_R);
}

if ( (status & ETH_DMA_IT_T) != (u32)RESET ) /* packet transmission */
{
rt_sem_release(&tx_buf_free);
ETH_DMAClearITPendingBit(ETH_DMA_IT_T);
}

/* Clear received IT */
if ((status & ETH_DMA_IT_NIS) != (u32)RESET)
ETH->DMASR = (u32)ETH_DMA_IT_NIS;
if ((status & ETH_DMA_IT_AIS) != (u32)RESET)
ETH->DMASR = (u32)ETH_DMA_IT_AIS;
if ((status & ETH_DMA_IT_RO) != (u32)RESET)
ETH->DMASR = (u32)ETH_DMA_IT_RO;

if ((status & ETH_DMA_IT_RBU) != (u32)RESET)
{
ETH_ResumeDMAReception();
ETH->DMASR = (u32)ETH_DMA_IT_RBU;
}

if ((status & ETH_DMA_IT_TBU) != (u32)RESET)
{
ETH_ResumeDMATransmission();
ETH->DMASR = (u32)ETH_DMA_IT_TBU;
}

/* leave interrupt */
rt_interrupt_leave();
}
Post by Gong Darcy
hi Greg and Max,
Have you looked at the ST STM32F10x RM0008 Reference manual yet?
The English version of section 28.6.9 section mentioned: (I see section
27.6.9 of the Chinese translation edition)
1) DMASR [7] interrupt occurs, may produce one or more DMASR [6] of the
interrupt is not processed
2) F107 DMA interrupt. If both multiple interrupt. Processed an interrupt
will then appear next. Also need to be cleared.
I suspect that part of the reason. I will do the checking. However, I am
new to the microcontroller. So the best you also check.
Darcy.
28.6.9 DMA interrupts
Interrupts can be generated as a result of various events. The ETH_DMASR
register
contains all the bits that might cause an interrupt. The ETH_DMAIER
register contains an
enable bit for each of the events that can cause an interrupt.
There are two groups of interrupts, Normal and Abnormal, as described in
the
ETH_DMASR register. Interrupts are cleared by writing a 1 to the
corresponding bit position.
When all the enabled interrupts within a group are cleared, the
corresponding summary bit
is cleared. If the MAC core is the cause for assertion of the interrupt,
then any of the TSTS
or PMTS bits in the ETH_DMASR register is set high.
Interrupts are not queued and if the interrupt event occurs before the
driver has responded
to it, no additional interrupts are generated. For example, the Receive
Interrupt bit
(ETH_DMASR register [6]) indicates that one or more frames were
transferred to the
STM32F107xx buffer. The driver must scan all descriptors, from the last
recorded position to
the first one owned by the DMA.
An interrupt is generated only once for simultaneous, multiple events. The
driver must scan
the ETH_DMASR register for the cause of the interrupt. The interrupt is
not generated again
unless a new interrupting event occurs, after the driver has cleared the
appropriate bit in the
ETH_DMASR register. For example, the controller generates a Receive
interrupt
(ETH_DMASR register[6]) and the driver begins reading the ETH_DMASR
register. Next,
receive buffer unavailable (ETH_DMASR register[7]) occurs. The driver
clears the Receive
interrupt. Even then, a new interrupt is generated, due to the active or
pending Receive
buffer unavailable interrupt.
Post by Gregory N
**
Hi, Max,
Post by Max Holtzberg
I also tried to get Ethernet working on a stm32f107.
Do you get "stm32_interrupt: Abormal event(s): 00008080" too?
(Maybe with CONFIG_DEBUG_VERBOSE=y)
I had no time yet to investigate that further...
I am now working with the Shenzhou STM32F107 board with Darcy. We have a
configuration (based largely on your Olimex configuration) and almost have
Ethernet working. But now we are seeing the same problem that you were
stm32_interrupt: Abormal event(s): 00008080
This happens frequently. When pinging from the target, this causes about
80% packet loss or more. When pinging from the host, it causes "No route to
host" or "Connectin time out"
"Bit 7 RBUS: Receive buffer unavailable status: This bit indicates that
the next descriptor in the receive list is owned by the host and cannot be
acquired by the DMA. Receive process is suspended. To resume processing
receive descriptors, the host should change the ownership of the descriptor
and issue a Receive Poll Demand command. If no Receive Poll Demand is
issued, receive process resumes when the next recognized incoming frame is
received. ETH_DMASR [7] is set only when the previous receive descriptor
was owned by the DMA."
1. Seven ECHO requests were sent from the target and nothing was received
(Wireshark was not running, but I am pretty sure that the ECHO requests
were sent and responded to).
2. On the 8th ECHO request, 8 ECHO responses are received back-to-back. I
have to assume that these were already in DMA memory, but there was no
interrupt event prior to this to inform the firmaware that the receive
packet is available.
3. Then 2 more ECHO requests were sent from target and nothing was
stm32_interrupt: Abormal event(s): 000180c0
stm32_interrupt: Abormal event(s): 00008080
stm32_interrupt: Abormal event(s): 00008080
The second two are your old friends. But the first also has bit 6 set
meaning that a receive interrupt is pending (but no interrupt was taken).
I don't understand the full cause of the 0008080 problem but I don't
believe that it is a PHY problem. I believe that it has to do with receive
interrupts not be taken. I believe that we happen to process some receive
packets when an interrupt happens to occur with the receive interrupt
pending, but I do not believe that the receive event is generating an
interrupt. As a result, eventually, you run out of buffers and the "Receive
Buffer Unavailable" interrupt ocurrs. At least that is my theory.
Do you have any insight? I will continue to look at this.
Greg
Gong Darcy
2012-09-24 08:58:50 UTC
Permalink
hi Greg and Max,

My Board is OK! Ping OK!
Thank you :)!
PS: Greg, to help look Boot problem DM9161AEP. Power On when not
working. To add delay. But I do not know where to add go.

Darcy

Modify a file stm32_eth.c:

-#define ETH_DMAINT_ABNORMAL \
- (ETH_DMAINT_TPSI | ETH_DMAINT_TJTI | ETH_DMAINT_ROI | ETH_DMAINT_TUI | \
- ETH_DMAINT_RBUI | ETH_DMAINT_RPSI | ETH_DMAINT_RWTI | /* ETH_DMAINT_ETI
| */ \
- ETH_DMAINT_FBEI)
+#define ETH_DMAINT_ABNORMAL \
+ (ETH_DMAINT_TPSI | ETH_DMAINT_TJTI | ETH_DMAINT_ROI | ETH_DMAINT_TUI | \
+ ETH_DMAINT_RBUI | ETH_DMAINT_TBUI | ETH_DMAINT_RPSI | ETH_DMAINT_RWTI |
/* ETH_DMAINT_ETI | */ \
+ ETH_DMAINT_FBEI)


/****************************************************************************
* Function: stm32_interrupt
*
* Description:
* Hardware interrupt handler
*
* Parameters:
* irq - Number of the IRQ that generated the interrupt
* context - Interrupt register state save info (architecture-specific)
*
* Returned Value:
* OK on success
*
* Assumptions:
*
****************************************************************************/

static int stm32_interrupt(int irq, FAR void *context)
{
register FAR struct stm32_ethmac_s *priv = &g_stm32ethmac[0];
uint32_t dmasr;

/* Get the DMA interrupt status bits (no MAC interrupts are expected) */

dmasr = stm32_getreg(STM32_ETH_DMASR);

/* Mask only enabled interrupts. This depends on the fact that the
interrupt
* related bits (0-16) correspond in these two registers.
*/

dmasr &= stm32_getreg(STM32_ETH_DMAIER);

/* Check if there are pending "normal" interrupts */

if ((dmasr & ETH_DMAINT_NIS) != 0)
{
/* Yes.. Check if we received an incoming packet, if so, call
* stm32_receive()
*/

if ((dmasr & ETH_DMAINT_RI) != 0)
{
//nlldbg("Abormal event(s) ETH_DMAINT_RI: %08x\n", dmasr);
/* Clear the pending receive interrupt */

stm32_putreg(ETH_DMAINT_RI, STM32_ETH_DMASR);

/* Handle the received package */

stm32_receive(priv);
}

/* Check if a packet transmission just completed. If so, call
* stm32_txdone(). This may disable further TX interrupts if there
* are no pending tansmissions.
*/

if ((dmasr & ETH_DMAINT_TI) != 0)
{
/* Clear the pending receive interrupt */

stm32_putreg(ETH_DMAINT_TI, STM32_ETH_DMASR);

/* Check if there are pending transmissions */

stm32_txdone(priv);
}

/* Clear the pending normal summary interrupt */

stm32_putreg(ETH_DMAINT_NIS, STM32_ETH_DMASR);
}

/* Handle error interrupt only if CONFIG_DEBUG_NET is eanbled */

#ifdef CONFIG_DEBUG_NET

/* Check if there are pending "anormal" interrupts */

if ((dmasr & ETH_DMAINT_AIS) != 0)
{
/* Just let the user know what happened */

nlldbg("Abormal event(s): %08x\n", dmasr);

if ((dmasr & ETH_DMAINT_RBUI) != 0)
{
stm32_putreg(0, STM32_ETH_DMARPDR);
}

if ((dmasr & ETH_DMAINT_TBUI) != 0)
{
stm32_putreg(0, STM32_ETH_DMATPDR);
}

/* Clear all pending abnormal events */

stm32_putreg(ETH_DMAINT_ABNORMAL, STM32_ETH_DMASR);

/* Clear the pending abnormal summary interrupt */

stm32_putreg(ETH_DMAINT_AIS, STM32_ETH_DMASR);
}
#endif

return OK;
}
Post by Gong Darcy
hi Greg and Max,
I compare the rt-thread stm32f107 code (can work).
Found that the differences in processing the interrupt function.
stm32_interrupt and ETH_IRQHandler (rt-thread)
ETH_IRQHandler for ETH_DMA_IT_RBU (DMASR [7]) to do the processing.
Reset This bit before. Running ETH_ResumeDMAReception () function.
This function is executed only ETH-> DMARPDR = 0;
Also detected ETH_DMA_IT_TBU (DMASR [2]) is set ETH -> DMATPDR = 0;
I will modify the code under test.
darcy
==============================================================
/**
*/
/**
register
* (the data written could be anything). This forces the DMA to resume
transmission.
*/
void ETH_ResumeDMATransmission(void)
{
ETH->DMATPDR = 0;
}
/**
register
* (the data written could be anything). This forces the DMA to resume
reception.
*/
void ETH_ResumeDMAReception(void)
{
ETH->DMARPDR = 0;
}
/* interrupt service routine for ETH */
void ETH_IRQHandler(void)
{
rt_uint32_t status;
/* enter interrupt */
rt_interrupt_enter();
/* get DMA IT status */
status = ETH->DMASR;
if ( (status & ETH_DMA_IT_R) != (u32)RESET ) /* packet receiption */
{
/* a frame has been received */
eth_device_ready(&(stm32_eth_device.parent));
ETH_DMAClearITPendingBit(ETH_DMA_IT_R);
}
if ( (status & ETH_DMA_IT_T) != (u32)RESET ) /* packet transmission */
{
rt_sem_release(&tx_buf_free);
ETH_DMAClearITPendingBit(ETH_DMA_IT_T);
}
/* Clear received IT */
if ((status & ETH_DMA_IT_NIS) != (u32)RESET)
ETH->DMASR = (u32)ETH_DMA_IT_NIS;
if ((status & ETH_DMA_IT_AIS) != (u32)RESET)
ETH->DMASR = (u32)ETH_DMA_IT_AIS;
if ((status & ETH_DMA_IT_RO) != (u32)RESET)
ETH->DMASR = (u32)ETH_DMA_IT_RO;
if ((status & ETH_DMA_IT_RBU) != (u32)RESET)
{
ETH_ResumeDMAReception();
ETH->DMASR = (u32)ETH_DMA_IT_RBU;
}
if ((status & ETH_DMA_IT_TBU) != (u32)RESET)
{
ETH_ResumeDMATransmission();
ETH->DMASR = (u32)ETH_DMA_IT_TBU;
}
/* leave interrupt */
rt_interrupt_leave();
}
Post by Gong Darcy
hi Greg and Max,
Have you looked at the ST STM32F10x RM0008 Reference manual yet?
The English version of section 28.6.9 section mentioned: (I see section
27.6.9 of the Chinese translation edition)
1) DMASR [7] interrupt occurs, may produce one or more DMASR [6] of the
interrupt is not processed
2) F107 DMA interrupt. If both multiple interrupt. Processed an interrupt
will then appear next. Also need to be cleared.
I suspect that part of the reason. I will do the checking. However, I am
new to the microcontroller. So the best you also check.
Darcy.
28.6.9 DMA interrupts
Interrupts can be generated as a result of various events. The ETH_DMASR
register
contains all the bits that might cause an interrupt. The ETH_DMAIER
register contains an
enable bit for each of the events that can cause an interrupt.
There are two groups of interrupts, Normal and Abnormal, as described in
the
ETH_DMASR register. Interrupts are cleared by writing a 1 to the
corresponding bit position.
When all the enabled interrupts within a group are cleared, the
corresponding summary bit
is cleared. If the MAC core is the cause for assertion of the interrupt,
then any of the TSTS
or PMTS bits in the ETH_DMASR register is set high.
Interrupts are not queued and if the interrupt event occurs before the
driver has responded
to it, no additional interrupts are generated. For example, the Receive
Interrupt bit
(ETH_DMASR register [6]) indicates that one or more frames were
transferred to the
STM32F107xx buffer. The driver must scan all descriptors, from the last
recorded position to
the first one owned by the DMA.
An interrupt is generated only once for simultaneous, multiple events.
The driver must scan
the ETH_DMASR register for the cause of the interrupt. The interrupt is
not generated again
unless a new interrupting event occurs, after the driver has cleared the
appropriate bit in the
ETH_DMASR register. For example, the controller generates a Receive
interrupt
(ETH_DMASR register[6]) and the driver begins reading the ETH_DMASR
register. Next,
receive buffer unavailable (ETH_DMASR register[7]) occurs. The driver
clears the Receive
interrupt. Even then, a new interrupt is generated, due to the active or
pending Receive
buffer unavailable interrupt.
Post by Gregory N
**
Hi, Max,
Post by Max Holtzberg
I also tried to get Ethernet working on a stm32f107.
Do you get "stm32_interrupt: Abormal event(s): 00008080" too?
(Maybe with CONFIG_DEBUG_VERBOSE=y)
I had no time yet to investigate that further...
I am now working with the Shenzhou STM32F107 board with Darcy. We have a
configuration (based largely on your Olimex configuration) and almost have
Ethernet working. But now we are seeing the same problem that you were
stm32_interrupt: Abormal event(s): 00008080
This happens frequently. When pinging from the target, this causes about
80% packet loss or more. When pinging from the host, it causes "No route to
host" or "Connectin time out"
"Bit 7 RBUS: Receive buffer unavailable status: This bit indicates that
the next descriptor in the receive list is owned by the host and cannot be
acquired by the DMA. Receive process is suspended. To resume processing
receive descriptors, the host should change the ownership of the descriptor
and issue a Receive Poll Demand command. If no Receive Poll Demand is
issued, receive process resumes when the next recognized incoming frame is
received. ETH_DMASR [7] is set only when the previous receive descriptor
was owned by the DMA."
I have debug output that shows the following sequence of events when I
1. Seven ECHO requests were sent from the target and nothing was
received (Wireshark was not running, but I am pretty sure that the ECHO
requests were sent and responded to).
2. On the 8th ECHO request, 8 ECHO responses are received back-to-back.
I have to assume that these were already in DMA memory, but there was no
interrupt event prior to this to inform the firmaware that the receive
packet is available.
3. Then 2 more ECHO requests were sent from target and nothing was
stm32_interrupt: Abormal event(s): 000180c0
stm32_interrupt: Abormal event(s): 00008080
stm32_interrupt: Abormal event(s): 00008080
The second two are your old friends. But the first also has bit 6 set
meaning that a receive interrupt is pending (but no interrupt was taken).
I don't understand the full cause of the 0008080 problem but I don't
believe that it is a PHY problem. I believe that it has to do with receive
interrupts not be taken. I believe that we happen to process some receive
packets when an interrupt happens to occur with the receive interrupt
pending, but I do not believe that the receive event is generating an
interrupt. As a result, eventually, you run out of buffers and the "Receive
Buffer Unavailable" interrupt ocurrs. At least that is my theory.
Do you have any insight? I will continue to look at this.
Greg
Gong Darcy
2012-09-24 09:07:34 UTC
Permalink
hi Greg,
Adjust shenzhou development board name?shenzhou STM32 development board is
a total of five models are shenzhou I (stm32f103rb) / shenzhou the II
(stm32f103vc), / shenzhou III (stm32f103ze) / shenzhou IV (stm32f107vc) /
shenzhou king ((stm32f103zg, core board + IO expansion board)).

darcy
Post by Gong Darcy
hi Greg and Max,
My Board is OK! Ping OK!
Thank you :)!
PS: Greg, to help look Boot problem DM9161AEP. Power On when not
working. To add delay. But I do not know where to add go.
Darcy
-#define ETH_DMAINT_ABNORMAL \
- (ETH_DMAINT_TPSI | ETH_DMAINT_TJTI | ETH_DMAINT_ROI | ETH_DMAINT_TUI | \
- ETH_DMAINT_RBUI | ETH_DMAINT_RPSI | ETH_DMAINT_RWTI | /*
ETH_DMAINT_ETI | */ \
- ETH_DMAINT_FBEI)
+#define ETH_DMAINT_ABNORMAL \
+ (ETH_DMAINT_TPSI | ETH_DMAINT_TJTI | ETH_DMAINT_ROI | ETH_DMAINT_TUI | \
+ ETH_DMAINT_RBUI | ETH_DMAINT_TBUI | ETH_DMAINT_RPSI | ETH_DMAINT_RWTI
| /* ETH_DMAINT_ETI | */ \
+ ETH_DMAINT_FBEI)
/****************************************************************************
* Function: stm32_interrupt
*
* Hardware interrupt handler
*
* irq - Number of the IRQ that generated the interrupt
* context - Interrupt register state save info (architecture-specific)
*
* OK on success
*
*
****************************************************************************/
static int stm32_interrupt(int irq, FAR void *context)
{
register FAR struct stm32_ethmac_s *priv = &g_stm32ethmac[0];
uint32_t dmasr;
/* Get the DMA interrupt status bits (no MAC interrupts are expected) */
dmasr = stm32_getreg(STM32_ETH_DMASR);
/* Mask only enabled interrupts. This depends on the fact that the
interrupt
* related bits (0-16) correspond in these two registers.
*/
dmasr &= stm32_getreg(STM32_ETH_DMAIER);
/* Check if there are pending "normal" interrupts */
if ((dmasr & ETH_DMAINT_NIS) != 0)
{
/* Yes.. Check if we received an incoming packet, if so, call
* stm32_receive()
*/
if ((dmasr & ETH_DMAINT_RI) != 0)
{
//nlldbg("Abormal event(s) ETH_DMAINT_RI: %08x\n", dmasr);
/* Clear the pending receive interrupt */
stm32_putreg(ETH_DMAINT_RI, STM32_ETH_DMASR);
/* Handle the received package */
stm32_receive(priv);
}
/* Check if a packet transmission just completed. If so, call
* stm32_txdone(). This may disable further TX interrupts if there
* are no pending tansmissions.
*/
if ((dmasr & ETH_DMAINT_TI) != 0)
{
/* Clear the pending receive interrupt */
stm32_putreg(ETH_DMAINT_TI, STM32_ETH_DMASR);
/* Check if there are pending transmissions */
stm32_txdone(priv);
}
/* Clear the pending normal summary interrupt */
stm32_putreg(ETH_DMAINT_NIS, STM32_ETH_DMASR);
}
/* Handle error interrupt only if CONFIG_DEBUG_NET is eanbled */
#ifdef CONFIG_DEBUG_NET
/* Check if there are pending "anormal" interrupts */
if ((dmasr & ETH_DMAINT_AIS) != 0)
{
/* Just let the user know what happened */
nlldbg("Abormal event(s): %08x\n", dmasr);
if ((dmasr & ETH_DMAINT_RBUI) != 0)
{
stm32_putreg(0, STM32_ETH_DMARPDR);
}
if ((dmasr & ETH_DMAINT_TBUI) != 0)
{
stm32_putreg(0, STM32_ETH_DMATPDR);
}
/* Clear all pending abnormal events */
stm32_putreg(ETH_DMAINT_ABNORMAL, STM32_ETH_DMASR);
/* Clear the pending abnormal summary interrupt */
stm32_putreg(ETH_DMAINT_AIS, STM32_ETH_DMASR);
}
#endif
return OK;
}
Post by Gong Darcy
hi Greg and Max,
I compare the rt-thread stm32f107 code (can work).
Found that the differences in processing the interrupt function.
stm32_interrupt and ETH_IRQHandler (rt-thread)
ETH_IRQHandler for ETH_DMA_IT_RBU (DMASR [7]) to do the processing.
Reset This bit before. Running ETH_ResumeDMAReception () function.
This function is executed only ETH-> DMARPDR = 0;
Also detected ETH_DMA_IT_TBU (DMASR [2]) is set ETH -> DMATPDR = 0;
I will modify the code under test.
darcy
==============================================================
/**
*/
/**
DmaTxPollDemand register
* (the data written could be anything). This forces the DMA to
resume transmission.
*/
void ETH_ResumeDMATransmission(void)
{
ETH->DMATPDR = 0;
}
/**
DmaRxPollDemand register
* (the data written could be anything). This forces the DMA to resume
reception.
*/
void ETH_ResumeDMAReception(void)
{
ETH->DMARPDR = 0;
}
/* interrupt service routine for ETH */
void ETH_IRQHandler(void)
{
rt_uint32_t status;
/* enter interrupt */
rt_interrupt_enter();
/* get DMA IT status */
status = ETH->DMASR;
if ( (status & ETH_DMA_IT_R) != (u32)RESET ) /* packet receiption */
{
/* a frame has been received */
eth_device_ready(&(stm32_eth_device.parent));
ETH_DMAClearITPendingBit(ETH_DMA_IT_R);
}
if ( (status & ETH_DMA_IT_T) != (u32)RESET ) /* packet transmission */
{
rt_sem_release(&tx_buf_free);
ETH_DMAClearITPendingBit(ETH_DMA_IT_T);
}
/* Clear received IT */
if ((status & ETH_DMA_IT_NIS) != (u32)RESET)
ETH->DMASR = (u32)ETH_DMA_IT_NIS;
if ((status & ETH_DMA_IT_AIS) != (u32)RESET)
ETH->DMASR = (u32)ETH_DMA_IT_AIS;
if ((status & ETH_DMA_IT_RO) != (u32)RESET)
ETH->DMASR = (u32)ETH_DMA_IT_RO;
if ((status & ETH_DMA_IT_RBU) != (u32)RESET)
{
ETH_ResumeDMAReception();
ETH->DMASR = (u32)ETH_DMA_IT_RBU;
}
if ((status & ETH_DMA_IT_TBU) != (u32)RESET)
{
ETH_ResumeDMATransmission();
ETH->DMASR = (u32)ETH_DMA_IT_TBU;
}
/* leave interrupt */
rt_interrupt_leave();
}
Post by Gong Darcy
hi Greg and Max,
Have you looked at the ST STM32F10x RM0008 Reference manual yet?
The English version of section 28.6.9 section mentioned: (I see section
27.6.9 of the Chinese translation edition)
1) DMASR [7] interrupt occurs, may produce one or more DMASR [6] of the
interrupt is not processed
2) F107 DMA interrupt. If both multiple interrupt. Processed an
interrupt will then appear next. Also need to be cleared.
I suspect that part of the reason. I will do the checking. However, I am
new to the microcontroller. So the best you also check.
Darcy.
28.6.9 DMA interrupts
Interrupts can be generated as a result of various events. The ETH_DMASR
register
contains all the bits that might cause an interrupt. The ETH_DMAIER
register contains an
enable bit for each of the events that can cause an interrupt.
There are two groups of interrupts, Normal and Abnormal, as described in
the
ETH_DMASR register. Interrupts are cleared by writing a 1 to the
corresponding bit position.
When all the enabled interrupts within a group are cleared, the
corresponding summary bit
is cleared. If the MAC core is the cause for assertion of the interrupt,
then any of the TSTS
or PMTS bits in the ETH_DMASR register is set high.
Interrupts are not queued and if the interrupt event occurs before the
driver has responded
to it, no additional interrupts are generated. For example, the Receive
Interrupt bit
(ETH_DMASR register [6]) indicates that one or more frames were
transferred to the
STM32F107xx buffer. The driver must scan all descriptors, from the last
recorded position to
the first one owned by the DMA.
An interrupt is generated only once for simultaneous, multiple events.
The driver must scan
the ETH_DMASR register for the cause of the interrupt. The interrupt is
not generated again
unless a new interrupting event occurs, after the driver has cleared the
appropriate bit in the
ETH_DMASR register. For example, the controller generates a Receive
interrupt
(ETH_DMASR register[6]) and the driver begins reading the ETH_DMASR
register. Next,
receive buffer unavailable (ETH_DMASR register[7]) occurs. The driver
clears the Receive
interrupt. Even then, a new interrupt is generated, due to the active or
pending Receive
buffer unavailable interrupt.
Post by Gregory N
**
Hi, Max,
Post by Max Holtzberg
I also tried to get Ethernet working on a stm32f107.
Do you get "stm32_interrupt: Abormal event(s): 00008080" too?
(Maybe with CONFIG_DEBUG_VERBOSE=y)
I had no time yet to investigate that further...
I am now working with the Shenzhou STM32F107 board with Darcy. We have
a configuration (based largely on your Olimex configuration) and almost
have Ethernet working. But now we are seeing the same problem that you were
stm32_interrupt: Abormal event(s): 00008080
This happens frequently. When pinging from the target, this causes
about 80% packet loss or more. When pinging from the host, it causes "No
route to host" or "Connectin time out"
"Bit 7 RBUS: Receive buffer unavailable status: This bit indicates that
the next descriptor in the receive list is owned by the host and cannot be
acquired by the DMA. Receive process is suspended. To resume processing
receive descriptors, the host should change the ownership of the descriptor
and issue a Receive Poll Demand command. If no Receive Poll Demand is
issued, receive process resumes when the next recognized incoming frame is
received. ETH_DMASR [7] is set only when the previous receive descriptor
was owned by the DMA."
I have debug output that shows the following sequence of events when I
1. Seven ECHO requests were sent from the target and nothing was
received (Wireshark was not running, but I am pretty sure that the ECHO
requests were sent and responded to).
2. On the 8th ECHO request, 8 ECHO responses are received back-to-back.
I have to assume that these were already in DMA memory, but there was no
interrupt event prior to this to inform the firmaware that the receive
packet is available.
3. Then 2 more ECHO requests were sent from target and nothing was
stm32_interrupt: Abormal event(s): 000180c0
stm32_interrupt: Abormal event(s): 00008080
stm32_interrupt: Abormal event(s): 00008080
The second two are your old friends. But the first also has bit 6 set
meaning that a receive interrupt is pending (but no interrupt was taken).
I don't understand the full cause of the 0008080 problem but I don't
believe that it is a PHY problem. I believe that it has to do with receive
interrupts not be taken. I believe that we happen to process some receive
packets when an interrupt happens to occur with the receive interrupt
pending, but I do not believe that the receive event is generating an
interrupt. As a result, eventually, you run out of buffers and the "Receive
Buffer Unavailable" interrupt ocurrs. At least that is my theory.
Do you have any insight? I will continue to look at this.
Greg
Gong Darcy
2012-09-24 09:20:20 UTC
Permalink
hi Greg,
I set CONFIG_NET_DEBUG = n. The network does not work.
Probably many valid code in on CONFIG_NET_DEBUG label. I'm afraid I will
part change chaos. Or do you do it.
darcy
Post by Gong Darcy
hi Greg and Max,
My Board is OK! Ping OK!
Thank you :)!
PS: Greg, to help look Boot problem DM9161AEP. Power On when not
working. To add delay. But I do not know where to add go.
Darcy
-#define ETH_DMAINT_ABNORMAL \
- (ETH_DMAINT_TPSI | ETH_DMAINT_TJTI | ETH_DMAINT_ROI | ETH_DMAINT_TUI | \
- ETH_DMAINT_RBUI | ETH_DMAINT_RPSI | ETH_DMAINT_RWTI | /*
ETH_DMAINT_ETI | */ \
- ETH_DMAINT_FBEI)
+#define ETH_DMAINT_ABNORMAL \
+ (ETH_DMAINT_TPSI | ETH_DMAINT_TJTI | ETH_DMAINT_ROI | ETH_DMAINT_TUI | \
+ ETH_DMAINT_RBUI | ETH_DMAINT_TBUI | ETH_DMAINT_RPSI | ETH_DMAINT_RWTI
| /* ETH_DMAINT_ETI | */ \
+ ETH_DMAINT_FBEI)
/****************************************************************************
* Function: stm32_interrupt
*
* Hardware interrupt handler
*
* irq - Number of the IRQ that generated the interrupt
* context - Interrupt register state save info (architecture-specific)
*
* OK on success
*
*
****************************************************************************/
static int stm32_interrupt(int irq, FAR void *context)
{
register FAR struct stm32_ethmac_s *priv = &g_stm32ethmac[0];
uint32_t dmasr;
/* Get the DMA interrupt status bits (no MAC interrupts are expected) */
dmasr = stm32_getreg(STM32_ETH_DMASR);
/* Mask only enabled interrupts. This depends on the fact that the
interrupt
* related bits (0-16) correspond in these two registers.
*/
dmasr &= stm32_getreg(STM32_ETH_DMAIER);
/* Check if there are pending "normal" interrupts */
if ((dmasr & ETH_DMAINT_NIS) != 0)
{
/* Yes.. Check if we received an incoming packet, if so, call
* stm32_receive()
*/
if ((dmasr & ETH_DMAINT_RI) != 0)
{
//nlldbg("Abormal event(s) ETH_DMAINT_RI: %08x\n", dmasr);
/* Clear the pending receive interrupt */
stm32_putreg(ETH_DMAINT_RI, STM32_ETH_DMASR);
/* Handle the received package */
stm32_receive(priv);
}
/* Check if a packet transmission just completed. If so, call
* stm32_txdone(). This may disable further TX interrupts if there
* are no pending tansmissions.
*/
if ((dmasr & ETH_DMAINT_TI) != 0)
{
/* Clear the pending receive interrupt */
stm32_putreg(ETH_DMAINT_TI, STM32_ETH_DMASR);
/* Check if there are pending transmissions */
stm32_txdone(priv);
}
/* Clear the pending normal summary interrupt */
stm32_putreg(ETH_DMAINT_NIS, STM32_ETH_DMASR);
}
/* Handle error interrupt only if CONFIG_DEBUG_NET is eanbled */
#ifdef CONFIG_DEBUG_NET
/* Check if there are pending "anormal" interrupts */
if ((dmasr & ETH_DMAINT_AIS) != 0)
{
/* Just let the user know what happened */
nlldbg("Abormal event(s): %08x\n", dmasr);
if ((dmasr & ETH_DMAINT_RBUI) != 0)
{
stm32_putreg(0, STM32_ETH_DMARPDR);
}
if ((dmasr & ETH_DMAINT_TBUI) != 0)
{
stm32_putreg(0, STM32_ETH_DMATPDR);
}
/* Clear all pending abnormal events */
stm32_putreg(ETH_DMAINT_ABNORMAL, STM32_ETH_DMASR);
/* Clear the pending abnormal summary interrupt */
stm32_putreg(ETH_DMAINT_AIS, STM32_ETH_DMASR);
}
#endif
return OK;
}
Post by Gong Darcy
hi Greg and Max,
I compare the rt-thread stm32f107 code (can work).
Found that the differences in processing the interrupt function.
stm32_interrupt and ETH_IRQHandler (rt-thread)
ETH_IRQHandler for ETH_DMA_IT_RBU (DMASR [7]) to do the processing.
Reset This bit before. Running ETH_ResumeDMAReception () function.
This function is executed only ETH-> DMARPDR = 0;
Also detected ETH_DMA_IT_TBU (DMASR [2]) is set ETH -> DMATPDR = 0;
I will modify the code under test.
darcy
==============================================================
/**
*/
/**
DmaTxPollDemand register
* (the data written could be anything). This forces the DMA to
resume transmission.
*/
void ETH_ResumeDMATransmission(void)
{
ETH->DMATPDR = 0;
}
/**
DmaRxPollDemand register
* (the data written could be anything). This forces the DMA to resume
reception.
*/
void ETH_ResumeDMAReception(void)
{
ETH->DMARPDR = 0;
}
/* interrupt service routine for ETH */
void ETH_IRQHandler(void)
{
rt_uint32_t status;
/* enter interrupt */
rt_interrupt_enter();
/* get DMA IT status */
status = ETH->DMASR;
if ( (status & ETH_DMA_IT_R) != (u32)RESET ) /* packet receiption */
{
/* a frame has been received */
eth_device_ready(&(stm32_eth_device.parent));
ETH_DMAClearITPendingBit(ETH_DMA_IT_R);
}
if ( (status & ETH_DMA_IT_T) != (u32)RESET ) /* packet transmission */
{
rt_sem_release(&tx_buf_free);
ETH_DMAClearITPendingBit(ETH_DMA_IT_T);
}
/* Clear received IT */
if ((status & ETH_DMA_IT_NIS) != (u32)RESET)
ETH->DMASR = (u32)ETH_DMA_IT_NIS;
if ((status & ETH_DMA_IT_AIS) != (u32)RESET)
ETH->DMASR = (u32)ETH_DMA_IT_AIS;
if ((status & ETH_DMA_IT_RO) != (u32)RESET)
ETH->DMASR = (u32)ETH_DMA_IT_RO;
if ((status & ETH_DMA_IT_RBU) != (u32)RESET)
{
ETH_ResumeDMAReception();
ETH->DMASR = (u32)ETH_DMA_IT_RBU;
}
if ((status & ETH_DMA_IT_TBU) != (u32)RESET)
{
ETH_ResumeDMATransmission();
ETH->DMASR = (u32)ETH_DMA_IT_TBU;
}
/* leave interrupt */
rt_interrupt_leave();
}
Post by Gong Darcy
hi Greg and Max,
Have you looked at the ST STM32F10x RM0008 Reference manual yet?
The English version of section 28.6.9 section mentioned: (I see section
27.6.9 of the Chinese translation edition)
1) DMASR [7] interrupt occurs, may produce one or more DMASR [6] of the
interrupt is not processed
2) F107 DMA interrupt. If both multiple interrupt. Processed an
interrupt will then appear next. Also need to be cleared.
I suspect that part of the reason. I will do the checking. However, I am
new to the microcontroller. So the best you also check.
Darcy.
28.6.9 DMA interrupts
Interrupts can be generated as a result of various events. The ETH_DMASR
register
contains all the bits that might cause an interrupt. The ETH_DMAIER
register contains an
enable bit for each of the events that can cause an interrupt.
There are two groups of interrupts, Normal and Abnormal, as described in
the
ETH_DMASR register. Interrupts are cleared by writing a 1 to the
corresponding bit position.
When all the enabled interrupts within a group are cleared, the
corresponding summary bit
is cleared. If the MAC core is the cause for assertion of the interrupt,
then any of the TSTS
or PMTS bits in the ETH_DMASR register is set high.
Interrupts are not queued and if the interrupt event occurs before the
driver has responded
to it, no additional interrupts are generated. For example, the Receive
Interrupt bit
(ETH_DMASR register [6]) indicates that one or more frames were
transferred to the
STM32F107xx buffer. The driver must scan all descriptors, from the last
recorded position to
the first one owned by the DMA.
An interrupt is generated only once for simultaneous, multiple events.
The driver must scan
the ETH_DMASR register for the cause of the interrupt. The interrupt is
not generated again
unless a new interrupting event occurs, after the driver has cleared the
appropriate bit in the
ETH_DMASR register. For example, the controller generates a Receive
interrupt
(ETH_DMASR register[6]) and the driver begins reading the ETH_DMASR
register. Next,
receive buffer unavailable (ETH_DMASR register[7]) occurs. The driver
clears the Receive
interrupt. Even then, a new interrupt is generated, due to the active or
pending Receive
buffer unavailable interrupt.
Post by Gregory N
**
Hi, Max,
Post by Max Holtzberg
I also tried to get Ethernet working on a stm32f107.
Do you get "stm32_interrupt: Abormal event(s): 00008080" too?
(Maybe with CONFIG_DEBUG_VERBOSE=y)
I had no time yet to investigate that further...
I am now working with the Shenzhou STM32F107 board with Darcy. We have
a configuration (based largely on your Olimex configuration) and almost
have Ethernet working. But now we are seeing the same problem that you were
stm32_interrupt: Abormal event(s): 00008080
This happens frequently. When pinging from the target, this causes
about 80% packet loss or more. When pinging from the host, it causes "No
route to host" or "Connectin time out"
"Bit 7 RBUS: Receive buffer unavailable status: This bit indicates that
the next descriptor in the receive list is owned by the host and cannot be
acquired by the DMA. Receive process is suspended. To resume processing
receive descriptors, the host should change the ownership of the descriptor
and issue a Receive Poll Demand command. If no Receive Poll Demand is
issued, receive process resumes when the next recognized incoming frame is
received. ETH_DMASR [7] is set only when the previous receive descriptor
was owned by the DMA."
I have debug output that shows the following sequence of events when I
1. Seven ECHO requests were sent from the target and nothing was
received (Wireshark was not running, but I am pretty sure that the ECHO
requests were sent and responded to).
2. On the 8th ECHO request, 8 ECHO responses are received back-to-back.
I have to assume that these were already in DMA memory, but there was no
interrupt event prior to this to inform the firmaware that the receive
packet is available.
3. Then 2 more ECHO requests were sent from target and nothing was
stm32_interrupt: Abormal event(s): 000180c0
stm32_interrupt: Abormal event(s): 00008080
stm32_interrupt: Abormal event(s): 00008080
The second two are your old friends. But the first also has bit 6 set
meaning that a receive interrupt is pending (but no interrupt was taken).
I don't understand the full cause of the 0008080 problem but I don't
believe that it is a PHY problem. I believe that it has to do with receive
interrupts not be taken. I believe that we happen to process some receive
packets when an interrupt happens to occur with the receive interrupt
pending, but I do not believe that the receive event is generating an
interrupt. As a result, eventually, you run out of buffers and the "Receive
Buffer Unavailable" interrupt ocurrs. At least that is my theory.
Do you have any insight? I will continue to look at this.
Greg
Gong Darcy
2012-09-24 09:52:51 UTC
Permalink
hi all,

Configuration
CONFIG_DEBUG = y
CONFIG_DEBUG_VERBOSE = n
CONFIG_DEBUG_NET = y
Try to use telnet to connect to port 23

Leads to the following questions:

darcy

netdev_register: Registered MAC: 00:00:00:00:00:00 as dev: eth0
stm32_ifdown: Taking the network down
stm32_ifup: Bringing up: 192.168.150.50
stm32_phyinit: Duplex: FULL Speed: 100 MBps
stm32_receive: DROPPED: Unknown type: 0800
Assertion failed at file:chip/stm32_eth.c line: 2014
sp: 200078d4
stack base: 200079c8
stack size: 000007fc
200078c0: 0801b248 08001435 00010044 200078dc 00000000 000007de 0801b248
00000000
200078e0: 20007958 080011e5 00000000 20000340 20005824 08005af9 20000340
08005f07
20007900: 20005ea8 20005824 080049b5 20000340 08005acd 20005e90 200055b8
0000000f
20007920: 00000000 08018017 08005829 0800582f 08005829 08003e3d e000e010
08000bdf
20007940: 00000000 00000000 00000000 2000568c 00000000 080003a3 200079a0
00000000
20007960: 00000000 00000000 2000568c 00000000 20005680 00000000 00000000
00000000
20007980: 00000000 00000000 00000000 00000000 20005674 080034cf 08003d60
61000000
200079a0: 08003d49 00000000 00000000 00000000 00000000 00000000 00000000
08003a6d
200079c0: 00000000 00000000 00000000 00000000 fd528b34 7aa2d221 00000120
80000810
R0: 00000000 00000000 00000000 00000000 00000000 00000000 2000568c 00000000
R8: 20005680 00000000 00000000 00000000 20005674 200079a0 080034cf 08003d60
xPSR: 61000000 PRIMASK: 00000000
Post by darcygong
hi Greg,
I set CONFIG_NET_DEBUG = n. The network does not work.
Probably many valid code in on CONFIG_NET_DEBUG label. I'm afraid I will
part change chaos. Or do you do it.
darcy
Post by Gong Darcy
hi Greg and Max,
My Board is OK! Ping OK!
Thank you :)!
PS: Greg, to help look Boot problem DM9161AEP. Power On when not
working. To add delay. But I do not know where to add go.
Darcy
-#define ETH_DMAINT_ABNORMAL \
- (ETH_DMAINT_TPSI | ETH_DMAINT_TJTI | ETH_DMAINT_ROI | ETH_DMAINT_TUI | \
- ETH_DMAINT_RBUI | ETH_DMAINT_RPSI | ETH_DMAINT_RWTI | /*
ETH_DMAINT_ETI | */ \
- ETH_DMAINT_FBEI)
+#define ETH_DMAINT_ABNORMAL \
+ (ETH_DMAINT_TPSI | ETH_DMAINT_TJTI | ETH_DMAINT_ROI | ETH_DMAINT_TUI | \
+ ETH_DMAINT_RBUI | ETH_DMAINT_TBUI | ETH_DMAINT_RPSI | ETH_DMAINT_RWTI
| /* ETH_DMAINT_ETI | */ \
+ ETH_DMAINT_FBEI)
/****************************************************************************
* Function: stm32_interrupt
*
* Hardware interrupt handler
*
* irq - Number of the IRQ that generated the interrupt
* context - Interrupt register state save info (architecture-specific)
*
* OK on success
*
*
****************************************************************************/
static int stm32_interrupt(int irq, FAR void *context)
{
register FAR struct stm32_ethmac_s *priv = &g_stm32ethmac[0];
uint32_t dmasr;
/* Get the DMA interrupt status bits (no MAC interrupts are expected) */
dmasr = stm32_getreg(STM32_ETH_DMASR);
/* Mask only enabled interrupts. This depends on the fact that the
interrupt
* related bits (0-16) correspond in these two registers.
*/
dmasr &= stm32_getreg(STM32_ETH_DMAIER);
/* Check if there are pending "normal" interrupts */
if ((dmasr & ETH_DMAINT_NIS) != 0)
{
/* Yes.. Check if we received an incoming packet, if so, call
* stm32_receive()
*/
if ((dmasr & ETH_DMAINT_RI) != 0)
{
//nlldbg("Abormal event(s) ETH_DMAINT_RI: %08x\n", dmasr);
/* Clear the pending receive interrupt */
stm32_putreg(ETH_DMAINT_RI, STM32_ETH_DMASR);
/* Handle the received package */
stm32_receive(priv);
}
/* Check if a packet transmission just completed. If so, call
* stm32_txdone(). This may disable further TX interrupts if there
* are no pending tansmissions.
*/
if ((dmasr & ETH_DMAINT_TI) != 0)
{
/* Clear the pending receive interrupt */
stm32_putreg(ETH_DMAINT_TI, STM32_ETH_DMASR);
/* Check if there are pending transmissions */
stm32_txdone(priv);
}
/* Clear the pending normal summary interrupt */
stm32_putreg(ETH_DMAINT_NIS, STM32_ETH_DMASR);
}
/* Handle error interrupt only if CONFIG_DEBUG_NET is eanbled */
#ifdef CONFIG_DEBUG_NET
/* Check if there are pending "anormal" interrupts */
if ((dmasr & ETH_DMAINT_AIS) != 0)
{
/* Just let the user know what happened */
nlldbg("Abormal event(s): %08x\n", dmasr);
if ((dmasr & ETH_DMAINT_RBUI) != 0)
{
stm32_putreg(0, STM32_ETH_DMARPDR);
}
if ((dmasr & ETH_DMAINT_TBUI) != 0)
{
stm32_putreg(0, STM32_ETH_DMATPDR);
}
/* Clear all pending abnormal events */
stm32_putreg(ETH_DMAINT_ABNORMAL, STM32_ETH_DMASR);
/* Clear the pending abnormal summary interrupt */
stm32_putreg(ETH_DMAINT_AIS, STM32_ETH_DMASR);
}
#endif
return OK;
}
Post by Gong Darcy
hi Greg and Max,
I compare the rt-thread stm32f107 code (can work).
Found that the differences in processing the interrupt function.
stm32_interrupt and ETH_IRQHandler (rt-thread)
ETH_IRQHandler for ETH_DMA_IT_RBU (DMASR [7]) to do the processing.
Reset This bit before. Running ETH_ResumeDMAReception () function.
This function is executed only ETH-> DMARPDR = 0;
Also detected ETH_DMA_IT_TBU (DMASR [2]) is set ETH -> DMATPDR = 0;
I will modify the code under test.
darcy
==============================================================
/**
*/
/**
DmaTxPollDemand register
* (the data written could be anything). This forces the DMA to
resume transmission.
*/
void ETH_ResumeDMATransmission(void)
{
ETH->DMATPDR = 0;
}
/**
DmaRxPollDemand register
* (the data written could be anything). This forces the DMA to
resume reception.
*/
void ETH_ResumeDMAReception(void)
{
ETH->DMARPDR = 0;
}
/* interrupt service routine for ETH */
void ETH_IRQHandler(void)
{
rt_uint32_t status;
/* enter interrupt */
rt_interrupt_enter();
/* get DMA IT status */
status = ETH->DMASR;
if ( (status & ETH_DMA_IT_R) != (u32)RESET ) /* packet receiption */
{
/* a frame has been received */
eth_device_ready(&(stm32_eth_device.parent));
ETH_DMAClearITPendingBit(ETH_DMA_IT_R);
}
if ( (status & ETH_DMA_IT_T) != (u32)RESET ) /* packet transmission */
{
rt_sem_release(&tx_buf_free);
ETH_DMAClearITPendingBit(ETH_DMA_IT_T);
}
/* Clear received IT */
if ((status & ETH_DMA_IT_NIS) != (u32)RESET)
ETH->DMASR = (u32)ETH_DMA_IT_NIS;
if ((status & ETH_DMA_IT_AIS) != (u32)RESET)
ETH->DMASR = (u32)ETH_DMA_IT_AIS;
if ((status & ETH_DMA_IT_RO) != (u32)RESET)
ETH->DMASR = (u32)ETH_DMA_IT_RO;
if ((status & ETH_DMA_IT_RBU) != (u32)RESET)
{
ETH_ResumeDMAReception();
ETH->DMASR = (u32)ETH_DMA_IT_RBU;
}
if ((status & ETH_DMA_IT_TBU) != (u32)RESET)
{
ETH_ResumeDMATransmission();
ETH->DMASR = (u32)ETH_DMA_IT_TBU;
}
/* leave interrupt */
rt_interrupt_leave();
}
Post by Gong Darcy
hi Greg and Max,
Have you looked at the ST STM32F10x RM0008 Reference manual yet?
The English version of section 28.6.9 section mentioned: (I see section
27.6.9 of the Chinese translation edition)
1) DMASR [7] interrupt occurs, may produce one or more DMASR [6] of the
interrupt is not processed
2) F107 DMA interrupt. If both multiple interrupt. Processed an
interrupt will then appear next. Also need to be cleared.
I suspect that part of the reason. I will do the checking. However, I
am new to the microcontroller. So the best you also check.
Darcy.
28.6.9 DMA interrupts
Interrupts can be generated as a result of various events. The
ETH_DMASR register
contains all the bits that might cause an interrupt. The ETH_DMAIER
register contains an
enable bit for each of the events that can cause an interrupt.
There are two groups of interrupts, Normal and Abnormal, as described
in the
ETH_DMASR register. Interrupts are cleared by writing a 1 to the
corresponding bit position.
When all the enabled interrupts within a group are cleared, the
corresponding summary bit
is cleared. If the MAC core is the cause for assertion of the
interrupt, then any of the TSTS
or PMTS bits in the ETH_DMASR register is set high.
Interrupts are not queued and if the interrupt event occurs before the
driver has responded
to it, no additional interrupts are generated. For example, the Receive
Interrupt bit
(ETH_DMASR register [6]) indicates that one or more frames were
transferred to the
STM32F107xx buffer. The driver must scan all descriptors, from the last
recorded position to
the first one owned by the DMA.
An interrupt is generated only once for simultaneous, multiple events.
The driver must scan
the ETH_DMASR register for the cause of the interrupt. The interrupt is
not generated again
unless a new interrupting event occurs, after the driver has cleared
the appropriate bit in the
ETH_DMASR register. For example, the controller generates a Receive
interrupt
(ETH_DMASR register[6]) and the driver begins reading the ETH_DMASR
register. Next,
receive buffer unavailable (ETH_DMASR register[7]) occurs. The driver
clears the Receive
interrupt. Even then, a new interrupt is generated, due to the active
or pending Receive
buffer unavailable interrupt.
Post by Gregory N
**
Hi, Max,
Post by Max Holtzberg
I also tried to get Ethernet working on a stm32f107.
Do you get "stm32_interrupt: Abormal event(s): 00008080" too?
(Maybe with CONFIG_DEBUG_VERBOSE=y)
I had no time yet to investigate that further...
I am now working with the Shenzhou STM32F107 board with Darcy. We have
a configuration (based largely on your Olimex configuration) and almost
have Ethernet working. But now we are seeing the same problem that you were
stm32_interrupt: Abormal event(s): 00008080
This happens frequently. When pinging from the target, this causes
about 80% packet loss or more. When pinging from the host, it causes "No
route to host" or "Connectin time out"
"Bit 7 RBUS: Receive buffer unavailable status: This bit indicates
that the next descriptor in the receive list is owned by the host and
cannot be acquired by the DMA. Receive process is suspended. To resume
processing receive descriptors, the host should change the ownership of the
descriptor and issue a Receive Poll Demand command. If no Receive Poll
Demand is issued, receive process resumes when the next recognized incoming
frame is received. ETH_DMASR [7] is set only when the previous receive
descriptor was owned by the DMA."
I have debug output that shows the following sequence of events when I
1. Seven ECHO requests were sent from the target and nothing was
received (Wireshark was not running, but I am pretty sure that the ECHO
requests were sent and responded to).
2. On the 8th ECHO request, 8 ECHO responses are received
back-to-back. I have to assume that these were already in DMA memory, but
there was no interrupt event prior to this to inform the firmaware that the
receive packet is available.
3. Then 2 more ECHO requests were sent from target and nothing was
stm32_interrupt: Abormal event(s): 000180c0
stm32_interrupt: Abormal event(s): 00008080
stm32_interrupt: Abormal event(s): 00008080
The second two are your old friends. But the first also has bit 6 set
meaning that a receive interrupt is pending (but no interrupt was taken).
I don't understand the full cause of the 0008080 problem but I don't
believe that it is a PHY problem. I believe that it has to do with receive
interrupts not be taken. I believe that we happen to process some receive
packets when an interrupt happens to occur with the receive interrupt
pending, but I do not believe that the receive event is generating an
interrupt. As a result, eventually, you run out of buffers and the "Receive
Buffer Unavailable" interrupt ocurrs. At least that is my theory.
Do you have any insight? I will continue to look at this.
Greg
Gong Darcy
2012-09-24 12:01:35 UTC
Permalink
hi Greg,

Continuous ping period of time (from the the PC ping development board),
will lead to the aforementioned problems.
Estimated to be more than ten minutes before the problem occurs.

darcy
Post by Gong Darcy
hi all,
Configuration
CONFIG_DEBUG = y
CONFIG_DEBUG_VERBOSE = n
CONFIG_DEBUG_NET = y
Try to use telnet to connect to port 23
darcy
netdev_register: Registered MAC: 00:00:00:00:00:00 as dev: eth0
stm32_ifdown: Taking the network down
stm32_ifup: Bringing up: 192.168.150.50
stm32_phyinit: Duplex: FULL Speed: 100 MBps
stm32_receive: DROPPED: Unknown type: 0800
Assertion failed at file:chip/stm32_eth.c line: 2014
sp: 200078d4
stack base: 200079c8
stack size: 000007fc
200078c0: 0801b248 08001435 00010044 200078dc 00000000 000007de 0801b248
00000000
200078e0: 20007958 080011e5 00000000 20000340 20005824 08005af9 20000340
08005f07
20007900: 20005ea8 20005824 080049b5 20000340 08005acd 20005e90 200055b8
0000000f
20007920: 00000000 08018017 08005829 0800582f 08005829 08003e3d e000e010
08000bdf
20007940: 00000000 00000000 00000000 2000568c 00000000 080003a3 200079a0
00000000
20007960: 00000000 00000000 2000568c 00000000 20005680 00000000 00000000
00000000
20007980: 00000000 00000000 00000000 00000000 20005674 080034cf 08003d60
61000000
200079a0: 08003d49 00000000 00000000 00000000 00000000 00000000 00000000
08003a6d
200079c0: 00000000 00000000 00000000 00000000 fd528b34 7aa2d221 00000120
80000810
R0: 00000000 00000000 00000000 00000000 00000000 00000000 2000568c 00000000
R8: 20005680 00000000 00000000 00000000 20005674 200079a0 080034cf 08003d60
xPSR: 61000000 PRIMASK: 00000000
Post by darcygong
hi Greg,
I set CONFIG_NET_DEBUG = n. The network does not work.
Probably many valid code in on CONFIG_NET_DEBUG label. I'm afraid I will
part change chaos. Or do you do it.
darcy
Post by Gong Darcy
hi Greg and Max,
My Board is OK! Ping OK!
Thank you :)!
PS: Greg, to help look Boot problem DM9161AEP. Power On when not
working. To add delay. But I do not know where to add go.
Darcy
-#define ETH_DMAINT_ABNORMAL \
- (ETH_DMAINT_TPSI | ETH_DMAINT_TJTI | ETH_DMAINT_ROI | ETH_DMAINT_TUI | \
- ETH_DMAINT_RBUI | ETH_DMAINT_RPSI | ETH_DMAINT_RWTI | /*
ETH_DMAINT_ETI | */ \
- ETH_DMAINT_FBEI)
+#define ETH_DMAINT_ABNORMAL \
+ (ETH_DMAINT_TPSI | ETH_DMAINT_TJTI | ETH_DMAINT_ROI | ETH_DMAINT_TUI | \
+ ETH_DMAINT_RBUI | ETH_DMAINT_TBUI | ETH_DMAINT_RPSI |
ETH_DMAINT_RWTI | /* ETH_DMAINT_ETI | */ \
+ ETH_DMAINT_FBEI)
/****************************************************************************
* Function: stm32_interrupt
*
* Hardware interrupt handler
*
* irq - Number of the IRQ that generated the interrupt
* context - Interrupt register state save info (architecture-specific)
*
* OK on success
*
*
****************************************************************************/
static int stm32_interrupt(int irq, FAR void *context)
{
register FAR struct stm32_ethmac_s *priv = &g_stm32ethmac[0];
uint32_t dmasr;
/* Get the DMA interrupt status bits (no MAC interrupts are expected) */
dmasr = stm32_getreg(STM32_ETH_DMASR);
/* Mask only enabled interrupts. This depends on the fact that the
interrupt
* related bits (0-16) correspond in these two registers.
*/
dmasr &= stm32_getreg(STM32_ETH_DMAIER);
/* Check if there are pending "normal" interrupts */
if ((dmasr & ETH_DMAINT_NIS) != 0)
{
/* Yes.. Check if we received an incoming packet, if so, call
* stm32_receive()
*/
if ((dmasr & ETH_DMAINT_RI) != 0)
{
//nlldbg("Abormal event(s) ETH_DMAINT_RI: %08x\n", dmasr);
/* Clear the pending receive interrupt */
stm32_putreg(ETH_DMAINT_RI, STM32_ETH_DMASR);
/* Handle the received package */
stm32_receive(priv);
}
/* Check if a packet transmission just completed. If so, call
* stm32_txdone(). This may disable further TX interrupts if there
* are no pending tansmissions.
*/
if ((dmasr & ETH_DMAINT_TI) != 0)
{
/* Clear the pending receive interrupt */
stm32_putreg(ETH_DMAINT_TI, STM32_ETH_DMASR);
/* Check if there are pending transmissions */
stm32_txdone(priv);
}
/* Clear the pending normal summary interrupt */
stm32_putreg(ETH_DMAINT_NIS, STM32_ETH_DMASR);
}
/* Handle error interrupt only if CONFIG_DEBUG_NET is eanbled */
#ifdef CONFIG_DEBUG_NET
/* Check if there are pending "anormal" interrupts */
if ((dmasr & ETH_DMAINT_AIS) != 0)
{
/* Just let the user know what happened */
nlldbg("Abormal event(s): %08x\n", dmasr);
if ((dmasr & ETH_DMAINT_RBUI) != 0)
{
stm32_putreg(0, STM32_ETH_DMARPDR);
}
if ((dmasr & ETH_DMAINT_TBUI) != 0)
{
stm32_putreg(0, STM32_ETH_DMATPDR);
}
/* Clear all pending abnormal events */
stm32_putreg(ETH_DMAINT_ABNORMAL, STM32_ETH_DMASR);
/* Clear the pending abnormal summary interrupt */
stm32_putreg(ETH_DMAINT_AIS, STM32_ETH_DMASR);
}
#endif
return OK;
}
Post by Gong Darcy
hi Greg and Max,
I compare the rt-thread stm32f107 code (can work).
Found that the differences in processing the interrupt function.
stm32_interrupt and ETH_IRQHandler (rt-thread)
ETH_IRQHandler for ETH_DMA_IT_RBU (DMASR [7]) to do the processing.
Reset This bit before. Running ETH_ResumeDMAReception () function.
This function is executed only ETH-> DMARPDR = 0;
Also detected ETH_DMA_IT_TBU (DMASR [2]) is set ETH -> DMATPDR = 0;
I will modify the code under test.
darcy
==============================================================
/**
*/
/**
DmaTxPollDemand register
* (the data written could be anything). This forces the DMA to
resume transmission.
*/
void ETH_ResumeDMATransmission(void)
{
ETH->DMATPDR = 0;
}
/**
DmaRxPollDemand register
* (the data written could be anything). This forces the DMA to
resume reception.
*/
void ETH_ResumeDMAReception(void)
{
ETH->DMARPDR = 0;
}
/* interrupt service routine for ETH */
void ETH_IRQHandler(void)
{
rt_uint32_t status;
/* enter interrupt */
rt_interrupt_enter();
/* get DMA IT status */
status = ETH->DMASR;
if ( (status & ETH_DMA_IT_R) != (u32)RESET ) /* packet receiption */
{
/* a frame has been received */
eth_device_ready(&(stm32_eth_device.parent));
ETH_DMAClearITPendingBit(ETH_DMA_IT_R);
}
if ( (status & ETH_DMA_IT_T) != (u32)RESET ) /* packet transmission */
{
rt_sem_release(&tx_buf_free);
ETH_DMAClearITPendingBit(ETH_DMA_IT_T);
}
/* Clear received IT */
if ((status & ETH_DMA_IT_NIS) != (u32)RESET)
ETH->DMASR = (u32)ETH_DMA_IT_NIS;
if ((status & ETH_DMA_IT_AIS) != (u32)RESET)
ETH->DMASR = (u32)ETH_DMA_IT_AIS;
if ((status & ETH_DMA_IT_RO) != (u32)RESET)
ETH->DMASR = (u32)ETH_DMA_IT_RO;
if ((status & ETH_DMA_IT_RBU) != (u32)RESET)
{
ETH_ResumeDMAReception();
ETH->DMASR = (u32)ETH_DMA_IT_RBU;
}
if ((status & ETH_DMA_IT_TBU) != (u32)RESET)
{
ETH_ResumeDMATransmission();
ETH->DMASR = (u32)ETH_DMA_IT_TBU;
}
/* leave interrupt */
rt_interrupt_leave();
}
Post by Gong Darcy
hi Greg and Max,
Have you looked at the ST STM32F10x RM0008 Reference manual yet?
The English version of section 28.6.9 section mentioned: (I see
section 27.6.9 of the Chinese translation edition)
1) DMASR [7] interrupt occurs, may produce one or more DMASR [6] of
the interrupt is not processed
2) F107 DMA interrupt. If both multiple interrupt. Processed an
interrupt will then appear next. Also need to be cleared.
I suspect that part of the reason. I will do the checking. However, I
am new to the microcontroller. So the best you also check.
Darcy.
28.6.9 DMA interrupts
Interrupts can be generated as a result of various events. The
ETH_DMASR register
contains all the bits that might cause an interrupt. The ETH_DMAIER
register contains an
enable bit for each of the events that can cause an interrupt.
There are two groups of interrupts, Normal and Abnormal, as described
in the
ETH_DMASR register. Interrupts are cleared by writing a 1 to the
corresponding bit position.
When all the enabled interrupts within a group are cleared, the
corresponding summary bit
is cleared. If the MAC core is the cause for assertion of the
interrupt, then any of the TSTS
or PMTS bits in the ETH_DMASR register is set high.
Interrupts are not queued and if the interrupt event occurs before the
driver has responded
to it, no additional interrupts are generated. For example, the
Receive Interrupt bit
(ETH_DMASR register [6]) indicates that one or more frames were
transferred to the
STM32F107xx buffer. The driver must scan all descriptors, from the
last recorded position to
the first one owned by the DMA.
An interrupt is generated only once for simultaneous, multiple events.
The driver must scan
the ETH_DMASR register for the cause of the interrupt. The interrupt
is not generated again
unless a new interrupting event occurs, after the driver has cleared
the appropriate bit in the
ETH_DMASR register. For example, the controller generates a Receive
interrupt
(ETH_DMASR register[6]) and the driver begins reading the ETH_DMASR
register. Next,
receive buffer unavailable (ETH_DMASR register[7]) occurs. The driver
clears the Receive
interrupt. Even then, a new interrupt is generated, due to the active
or pending Receive
buffer unavailable interrupt.
Post by Gregory N
**
Hi, Max,
Post by Max Holtzberg
I also tried to get Ethernet working on a stm32f107.
Do you get "stm32_interrupt: Abormal event(s): 00008080" too?
(Maybe with CONFIG_DEBUG_VERBOSE=y)
I had no time yet to investigate that further...
I am now working with the Shenzhou STM32F107 board with Darcy. We
have a configuration (based largely on your Olimex configuration) and
almost have Ethernet working. But now we are seeing the same problem that
stm32_interrupt: Abormal event(s): 00008080
This happens frequently. When pinging from the target, this causes
about 80% packet loss or more. When pinging from the host, it causes "No
route to host" or "Connectin time out"
"Bit 7 RBUS: Receive buffer unavailable status: This bit indicates
that the next descriptor in the receive list is owned by the host and
cannot be acquired by the DMA. Receive process is suspended. To resume
processing receive descriptors, the host should change the ownership of the
descriptor and issue a Receive Poll Demand command. If no Receive Poll
Demand is issued, receive process resumes when the next recognized incoming
frame is received. ETH_DMASR [7] is set only when the previous receive
descriptor was owned by the DMA."
I have debug output that shows the following sequence of events when
1. Seven ECHO requests were sent from the target and nothing was
received (Wireshark was not running, but I am pretty sure that the ECHO
requests were sent and responded to).
2. On the 8th ECHO request, 8 ECHO responses are received
back-to-back. I have to assume that these were already in DMA memory, but
there was no interrupt event prior to this to inform the firmaware that the
receive packet is available.
3. Then 2 more ECHO requests were sent from target and nothing was
stm32_interrupt: Abormal event(s): 000180c0
stm32_interrupt: Abormal event(s): 00008080
stm32_interrupt: Abormal event(s): 00008080
The second two are your old friends. But the first also has bit 6 set
meaning that a receive interrupt is pending (but no interrupt was taken).
I don't understand the full cause of the 0008080 problem but I don't
believe that it is a PHY problem. I believe that it has to do with receive
interrupts not be taken. I believe that we happen to process some receive
packets when an interrupt happens to occur with the receive interrupt
pending, but I do not believe that the receive event is generating an
interrupt. As a result, eventually, you run out of buffers and the "Receive
Buffer Unavailable" interrupt ocurrs. At least that is my theory.
Do you have any insight? I will continue to look at this.
Greg
Loading...