W tym poście chciałbym opisać podstawową konfigurację Ethernet'u na płycie z układem STM32H725VGTx.
Podłączenie:
W projekcie wykorzystuje układ LAN8720. Jego sterowniki są możliwe do pobrania bezpośrednio z programu CubeMx.
W sterowniku dostępnym z poziomu CubeMx brakuje zdefiniowana dwóch pinów PHY_RXER oraz PHY_RESET. Oba piny są domyślnie podciągnięte pod VCC.
Pin PHY_RXER może być podciągnięty do VCC lub gdy niewykorzystywany należy go podciągnąć przez rezystor do GND.
Aby zresetować układ należy ustawić pin w stan niski. Powrót do normalnej pracy następuje po ponownym ustawieniu stanu wysokiego. Drugi pin wystawia informację, że nastąpił błąd w ramce danych. Pierwszy ze wspomnianych wyprowadzeń musi być skonfigurowany jako wyjście, ponieważ reset jest sterowany z mikrokontrolera. PHY_RXER należy skonfigurować jako wejście, i ustawić odpowiednie dane w rejestrach tak aby przesyłał informację o błędzie.
Konfiguracja:
W projekcie wykorzystałem układ LAN8720, to jego sterownik jest możliwy do dołożenia bezpośrednio z bibliotek CubeMx, podczas deklaracji projektu. Wobec tego samo uruchomienie działającego ETH na poprawnie zaprojektowanej płycie zajmuje kilka minut.
Konfiguracja biblioteki LWIP:
Po wygenerowaniu projektu wprowadzam kilka zmian.
Gdy wszystko zostanie poprawnie ustawione w CubeMx to w pliku FLASH znajdziemy przygotowaną konfigurację pamięci:
- .lwip_sec (NOLOAD) : {
- . = ABSOLUTE(0x30000000);
- *(.RxDecripSection)
- . = ABSOLUTE(0x30000060);
- *(.TxDecripSection)
- . = ABSOLUTE(0x30000200);
- *(.RxArraySection)
- } >RAM_D2 AT> ROM
Deskryptory zostały zdefiniowane w pliku ethernetif.c:
- #if defined ( __ICCARM__ ) /*!< IAR Compiler */
- #pragma location=0x30004000
- ETH_DMADescTypeDef DMARxDscrTab[ETH_RX_DESC_CNT]; /* Ethernet Rx DMA Descriptors */
- #pragma location=0x30004060
- ETH_DMADescTypeDef DMATxDscrTab[ETH_TX_DESC_CNT]; /* Ethernet Tx DMA Descriptors */
- #pragma location=0x30004200
- uint8_t Rx_Buff[ETH_RX_DESC_CNT][ETH_RX_BUFFER_SIZE]; /* Ethernet Receive Buffers */
- #elif defined ( __CC_ARM ) /* MDK ARM Compiler */
- __attribute__((at(0x30004000))) ETH_DMADescTypeDef DMARxDscrTab[ETH_RX_DESC_CNT]; /* Ethernet Rx DMA Descriptors */
- __attribute__((at(0x30004060))) ETH_DMADescTypeDef DMATxDscrTab[ETH_TX_DESC_CNT]; /* Ethernet Tx DMA Descriptors */
- __attribute__((at(0x30004200))) uint8_t Rx_Buff[ETH_RX_DESC_CNT][ETH_RX_BUFFER_SIZE]; /* Ethernet Receive Buffer */
- #elif defined ( __GNUC__ ) /* GNU Compiler */
- ETH_DMADescTypeDef DMARxDscrTab[ETH_RX_DESC_CNT] __attribute__((section(".RxDecripSection"))); /* Ethernet Rx DMA Descriptors */
- ETH_DMADescTypeDef DMATxDscrTab[ETH_TX_DESC_CNT] __attribute__((section(".TxDecripSection"))); /* Ethernet Tx DMA Descriptors */
- uint8_t Rx_Buff[ETH_RX_DESC_CNT][ETH_RX_BUFFER_SIZE] __attribute__((section(".RxArraySection"))); /* Ethernet Receive Buffers */
- #endif
Po konfiguracji i uruchomieniu projektu sprawdzam przesyłanie informacji z pingiem:
Do projektu dołożyłem konfigurację jako TCP Server Echo. Inicjalizacja:
- void tcp_echoserver_init(void)
- {
- tcp_echoserver_pcb = tcp_new();
- if (tcp_echoserver_pcb != NULL)
- {
- err_t err;
- err = tcp_bind(tcp_echoserver_pcb, IP_ADDR_ANY, 1025);
- if (err == ERR_OK)
- {
- tcp_echoserver_pcb = tcp_listen(tcp_echoserver_pcb);
- tcp_accept(tcp_echoserver_pcb, tcp_echoserver_accept);
- }
- else
- {
- memp_free(MEMP_TCP_PCB, tcp_echoserver_pcb);
- }
- }
- }
Do testu połączenia wykorzystałem program Hercules: