DDDDRRRRR 1 March 21, 2025 Posted March 21, 2025 · Report post Решил проблему, что-то было не пропаяно. Кучу раз все проверял, подпаивал, но помогла только основательная пропайка всего (lan и мк). Какое именно место было проблемное не знаю, так как все сигналы были в норме и визуально тоже проблем не наблюдалось. В процессе издевался над nucleo и словил такое же поведение, пропайка так же все решила. На самом деле мне не понятно почему так получилось, паял нормально, но по-хорошему, видимо, такое надо собирать на линии с автоматической расстановкой и пайкой. Ну или как вариант, плохо отмыл флюс (хотя использовал безотмывочный). Раз кучу времени потратил на поиск проблем и отладку, опишу, что понял, может кому поможет. - Пропаиваем все основательно, даже если все выглядит нормально. Отмываем так же. Обязательно безотмывочный флюс. - Читаем документацию, там много полезного. - Кварцевый резонатор 25 МГц я ставил DSX530G, но лучше ABM3. Конденсаторы 27 пФ, но проверял от 12 до 30 пФ, кварц работает. Контролировать можно по 14 пину, при нормальной работе кварца там будет синус 50 МГц почти 4 Вольта, единственный такой сигнал, остальные 3.3В. - Читаем регистры, положение старшего и младшего битов можно определить по нулевому регистру BCR, у него первые 8 бит (0-7) зарезервированы нулями. Контролировать можно логическим анализатором (пины MDC и MDIO). Код чтения регистров: Спойлер // PHY address #define LAN8742_PHY_ADDR 0 //LAN8742 PHY registers #define LAN8742_BMCR 0x00 #define LAN8742_BMSR 0x01 #define LAN8742_PHYID1 0x02 #define LAN8742_PHYID2 0x03 #define LAN8742_ANAR 0x04 #define LAN8742_ANLPAR 0x05 #define LAN8742_ANER 0x06 #define LAN8742_ANNPTR 0x07 #define LAN8742_ANNPRR 0x08 #define LAN8742_MMDACR 0x0D #define LAN8742_MMDAADR 0x0E #define LAN8742_ENCTR 0x10 #define LAN8742_MCSR 0x11 #define LAN8742_SMR 0x12 #define LAN8742_TDRPDCR 0x18 #define LAN8742_TDRCSR 0x19 #define LAN8742_SECR 0x1A #define LAN8742_SCSIR 0x1B #define LAN8742_CLR 0x1C #define LAN8742_ISR 0x1D #define LAN8742_IMR 0x1E #define LAN8742_PSCSR 0x1F //LAN8742 MMD registers #define LAN8742_PCS_MMD_DEV_PRES1 0x03, 0x0005 #define LAN8742_PCS_MMD_DEV_PRES2 0x03, 0x0006 #define LAN8742_WUCSR 0x03, 0x8010 #define LAN8742_WUF_CFGA 0x03, 0x8011 #define LAN8742_WUF_CFGB 0x03, 0x8012 #define LAN8742_WUF_MASK 0x03, 0x8021 #define LAN8742_RX_ADDRA 0x03, 0x8061 #define LAN8742_RX_ADDRB 0x03, 0x8062 #define LAN8742_RX_ADDRC 0x03, 0x8063 #define LAN8742_MCFGR 0x03, 0x8064 #define LAN8742_VENDOR_SPECIFIC_MMD1_DEV_ID1 0x1E, 0x0002 #define LAN8742_VENDOR_SPECIFIC_MMD1_DEV_ID2 0x1E, 0x0003 #define LAN8742_VENDOR_SPECIFIC_MMD1_DEV_PRES1 0x1E, 0x0005 #define LAN8742_VENDOR_SPECIFIC_MMD1_DEV_PRES2 0x1E, 0x0006 #define LAN8742_VENDOR_SPECIFIC_MMD1_STAT 0x1E, 0x0008 #define LAN8742_TDR_MATCH_THRESHOLD 0x1E, 0x000B #define LAN8742_TDR_SHORT_OPEN_THRESHOLD 0x1E, 0x000C #define LAN8742_VENDOR_SPECIFIC_MMD1_PKG_ID1 0x1E, 0x000E #define LAN8742_VENDOR_SPECIFIC_MMD1_PKG_ID2 0x1E, 0x000F //Basic Control register #define LAN8742_BMCR_RESET 0x8000 #define LAN8742_BMCR_LOOPBACK 0x4000 #define LAN8742_BMCR_SPEED_SEL 0x2000 #define LAN8742_BMCR_AN_EN 0x1000 #define LAN8742_BMCR_POWER_DOWN 0x0800 #define LAN8742_BMCR_ISOLATE 0x0400 #define LAN8742_BMCR_RESTART_AN 0x0200 #define LAN8742_BMCR_DUPLEX_MODE 0x0100 //Basic Status register #define LAN8742_BMSR_100BT4 0x8000 #define LAN8742_BMSR_100BTX_FD 0x4000 #define LAN8742_BMSR_100BTX_HD 0x2000 #define LAN8742_BMSR_10BT_FD 0x1000 #define LAN8742_BMSR_10BT_HD 0x0800 #define LAN8742_BMSR_100BT2_FD 0x0400 #define LAN8742_BMSR_100BT2_HD 0x0200 #define LAN8742_BMSR_EXTENDED_STATUS 0x0100 #define LAN8742_BMSR_AN_COMPLETE 0x0020 #define LAN8742_BMSR_REMOTE_FAULT 0x0010 #define LAN8742_BMSR_AN_CAPABLE 0x0008 #define LAN8742_BMSR_LINK_STATUS 0x0004 #define LAN8742_BMSR_JABBER_DETECT 0x0002 #define LAN8742_BMSR_EXTENDED_CAPABLE 0x0001 //PHY Identifier 1 register #define LAN8742_PHYID1_PHY_ID_MSB 0xFFFF #define LAN8742_PHYID1_PHY_ID_MSB_DEFAULT 0x0007 //PHY Identifier 2 register #define LAN8742_PHYID2_PHY_ID_LSB 0xFC00 #define LAN8742_PHYID2_PHY_ID_LSB_DEFAULT 0xC000 #define LAN8742_PHYID2_MODEL_NUM 0x03F0 #define LAN8742_PHYID2_MODEL_NUM_DEFAULT 0x0130 #define LAN8742_PHYID2_REVISION_NUM 0x000F //Auto-Negotiation Advertisement register #define LAN8742_ANAR_NEXT_PAGE 0x8000 #define LAN8742_ANAR_REMOTE_FAULT 0x2000 #define LAN8742_ANAR_PAUSE 0x0C00 #define LAN8742_ANAR_100BTX_FD 0x0100 #define LAN8742_ANAR_100BTX_HD 0x0080 #define LAN8742_ANAR_10BT_FD 0x0040 #define LAN8742_ANAR_10BT_HD 0x0020 #define LAN8742_ANAR_SELECTOR 0x001F #define LAN8742_ANAR_SELECTOR_DEFAULT 0x0001 //Auto-Negotiation Link Partner Ability register #define LAN8742_ANLPAR_NEXT_PAGE 0x8000 #define LAN8742_ANLPAR_ACK 0x4000 #define LAN8742_ANLPAR_REMOTE_FAULT 0x2000 #define LAN8742_ANLPAR_PAUSE 0x0400 #define LAN8742_ANLPAR_100BT4 0x0200 #define LAN8742_ANLPAR_100BTX_FD 0x0100 #define LAN8742_ANLPAR_100BTX_HD 0x0080 #define LAN8742_ANLPAR_10BT_FD 0x0040 #define LAN8742_ANLPAR_10BT_HD 0x0020 #define LAN8742_ANLPAR_SELECTOR 0x001F #define LAN8742_ANLPAR_SELECTOR_DEFAULT 0x0001 //Auto-Negotiation Expansion register #define LAN8742_ANER_RECEIVE_NP_LOC_ABLE 0x0040 #define LAN8742_ANER_RECEIVE_NP_STOR_LOC 0x0020 #define LAN8742_ANER_PAR_DETECT_FAULT 0x0010 #define LAN8742_ANER_LP_NEXT_PAGE_ABLE 0x0008 #define LAN8742_ANER_NEXT_PAGE_ABLE 0x0004 #define LAN8742_ANER_PAGE_RECEIVED 0x0002 #define LAN8742_ANER_LP_AN_ABLE 0x0001 //Auto Negotiation Next Page TX register #define LAN8742_ANNPTR_NEXT_PAGE 0x8000 #define LAN8742_ANNPTR_MSG_PAGE 0x2000 #define LAN8742_ANNPTR_ACK2 0x1000 #define LAN8742_ANNPTR_TOGGLE 0x0800 #define LAN8742_ANNPTR_MESSAGE 0x07FF //Auto Negotiation Next Page RX register #define LAN8742_ANNPRR_NEXT_PAGE 0x8000 #define LAN8742_ANNPRR_ACK 0x4000 #define LAN8742_ANNPRR_MSG_PAGE 0x2000 #define LAN8742_ANNPRR_ACK2 0x1000 #define LAN8742_ANNPRR_TOGGLE 0x0800 #define LAN8742_ANNPRR_MESSAGE 0x07FF //MMD Access Control register #define LAN8742_MMDACR_FUNC 0xC000 #define LAN8742_MMDACR_FUNC_ADDR 0x0000 #define LAN8742_MMDACR_FUNC_DATA_NO_POST_INC 0x4000 #define LAN8742_MMDACR_DEVAD 0x001F //EDPD NLP/Crossover Time Configuration register #define LAN8742_ENCTR_EDPD_TX_NLP_EN 0x8000 #define LAN8742_ENCTR_EDPD_TX_NLP_ITS 0x6000 #define LAN8742_ENCTR_EDPD_RX_NLP_WAKE_EN 0x1000 #define LAN8742_ENCTR_EDPD_RX_NLP_MIDS 0x0C00 #define LAN8742_ENCTR_EDPD_EXT_CROSSOVER 0x0002 #define LAN8742_ENCTR_EXT_CROSSOVER_TIME 0x0001 //Mode Control/Status register #define LAN8742_MCSR_EDPWRDOWN 0x2000 #define LAN8742_MCSR_FARLOOPBACK 0x0200 #define LAN8742_MCSR_ALTINT 0x0040 #define LAN8742_MCSR_ENERGYON 0x0002 //Special Modes register #define LAN8742_SMR_MODE 0x00E0 #define LAN8742_SMR_PHYAD 0x001F //TDR Patterns/Delay Control register #define LAN8742_TDRPDCR_DELAY_IN 0x8000 #define LAN8742_TDRPDCR_LINE_BREAK_COUNT 0x7000 #define LAN8742_TDRPDCR_PATTERN_HIGH 0x0FC0 #define LAN8742_TDRPDCR_PATTERN_LOW 0x003F //TDR Control/Status register #define LAN8742_TDRCSR_TDR_EN 0x8000 #define LAN8742_TDRCSR_AD_FILTER_EN 0x4000 #define LAN8742_TDRCSR_CH_CABLE_TYPE 0x0600 #define LAN8742_TDRCSR_CH_STATUS 0x0100 #define LAN8742_TDRCSR_CH_LENGTH 0x00FF //Symbol Error Counter register #define LAN8742_SECR_SYM_ERR_CNT 0xFFFF //Special Control/Status Indication register #define LAN8742_SCSIR_AMDIXCTRL 0x8000 #define LAN8742_SCSIR_CH_SELECT 0x2000 #define LAN8742_SCSIR_SQEOFF 0x0800 #define LAN8742_SCSIR_XPOL 0x0010 //Cable Length register #define LAN8742_CLR_CBLN 0xF000 //Interrupt Source Flag register #define LAN8742_ISR_WOL 0x0100 #define LAN8742_ISR_ENERGYON 0x0080 #define LAN8742_ISR_AN_COMPLETE 0x0040 #define LAN8742_ISR_REMOTE_FAULT 0x0020 #define LAN8742_ISR_LINK_DOWN 0x0010 #define LAN8742_ISR_AN_LP_ACK 0x0008 #define LAN8742_ISR_PAR_DETECT_FAULT 0x0004 #define LAN8742_ISR_AN_PAGE_RECEIVED 0x0002 //Interrupt Mask register #define LAN8742_IMR_WOL 0x0100 #define LAN8742_IMR_ENERGYON 0x0080 #define LAN8742_IMR_AN_COMPLETE 0x0040 #define LAN8742_IMR_REMOTE_FAULT 0x0020 #define LAN8742_IMR_LINK_DOWN 0x0010 #define LAN8742_IMR_AN_LP_ACK 0x0008 #define LAN8742_IMR_PAR_DETECT_FAULT 0x0004 #define LAN8742_IMR_AN_PAGE_RECEIVED 0x0002 //PHY Special Control/Status register #define LAN8742_PSCSR_AUTODONE 0x1000 #define LAN8742_PSCSR_HCDSPEED 0x001C #define LAN8742_PSCSR_HCDSPEED_10BT_HD 0x0004 #define LAN8742_PSCSR_HCDSPEED_100BTX_HD 0x0008 #define LAN8742_PSCSR_HCDSPEED_10BT_FD 0x0014 #define LAN8742_PSCSR_HCDSPEED_100BTX_FD 0x0018 char binaryStr[17]; uint16_t RegVal = 0; void int_to_binary(uint16_t num, char *binaryStr) { for(uint8_t i = 0; i < 16; ++i) { binaryStr[i] = (num % 2) ? '1' : '0'; num /= 2; } binaryStr[16] = '\0'; } void lan8742WritePhyReg(uint8_t address, uint16_t data) { HAL_ETH_WritePHYRegister(&heth, address, data); } uint16_t lan8742ReadPhyReg(uint8_t address) { uint16_t data; HAL_ETH_ReadPHYRegister(&heth, address, &data); return data; } uint16_t lan8742ReadMmdReg(uint8_t devAddr, uint16_t regAddr) { lan8742WritePhyReg(LAN8742_MMDACR, LAN8742_MMDACR_FUNC_ADDR | (devAddr & LAN8742_MMDACR_DEVAD)); lan8742WritePhyReg(LAN8742_MMDAADR, regAddr); lan8742WritePhyReg(LAN8742_MMDACR, LAN8742_MMDACR_FUNC_DATA_NO_POST_INC | (devAddr & LAN8742_MMDACR_DEVAD)); return lan8742ReadPhyReg(LAN8742_MMDAADR); } RegVal = lan8742ReadPhyReg(LAN8742_BMCR); int_to_binary(RegVal, binaryStr); snprintf(SendStr, 50, "%s\r\n", binaryStr); HAL_UART_Transmit(&H_USART_DEBUG, (uint8_t*)SendStr, strlen(SendStr), 100);*/ Функции чтения взял отсюда: https://www.oryx-embedded.com/doc/lan8742__driver_8c.html - Режим Loopback: 14й (0-15) бит BCR может активировать режим, при котором все отправленные данные lan8742a сразу же направляет в буфер приема. Я смог его активировать, сделать отправку пакета данных, но принять ничего у меня не получилось. Скорее всего lan резал пакет из-за его заголовка. Причину не знаю, вообще большой минус — это то, что работу PHY я брал из HAL, там найти концы и выдернуть оттуда работу с нижним уровнем сложно. При этом HAL в процессе сам постоянно вмешивается в регистры LAN. Код отправки фрейма: Спойлер #define ETHERNET_HEADER_SIZE 14 // Размер заголовка Ethernet uint8_t payload[] = "Hello, Ethernet!"; // Данные, которые мы хотим отправить #define FRAME_LENGTH (ETHERNET_HEADER_SIZE + sizeof(payload)) // Общая длина пакета uint8_t ethernet_frame[FRAME_LENGTH]; // Буфер для полного Ethernet-кадра ETH_HandleTypeDef heth; void prepare_ethernet_frame() { // Заполняем Ethernet заголовок uint8_t src_mac[6] = {0x00, 0x80, 0xE1, 0x22, 0x33, 0x44}; uint8_t dest_mac[6] = {0x00, 0x80, 0xE1, 0x11, 0x22, 0x33}; // Копируем заголовок memcpy(ethernet_frame, dest_mac, 6); // Копируем MAC-адрес получателя memcpy(ethernet_frame + 6, src_mac, 6); // Копируем MAC-адрес отправителя // Устанавливаем тип протокола (например, IPv4) ethernet_frame[12] = 0x08; // Тип выше расположенного протокола (для IPv4 0x08 0x00) ethernet_frame[13] = 0x00; // Копируем полезную нагрузку в кадр memcpy(ethernet_frame + ETHERNET_HEADER_SIZE, payload, sizeof(payload)); // Заполняем буфер данных для передачи heth.TxDesc->Buffer1Addr = (uint32_t)ethernet_frame; // Указатель на буфер данных heth.TxDesc->ControlBufferSize = (31 & ETH_DMATXDESC_TBS1); // Устанавливаем размер кадра } void send_data() { prepare_ethernet_frame(); HAL_ETH_TransmitFrame(&heth, FRAME_LENGTH); } В цикле с периодичностью вызываем send_data(); - Простой TCP сервер Спойлер #include "lwip/netif.h" #include "lwip/ip_addr.h" #include "lwip/opt.h" #include "lwip/udp.h" #include "lwip/ip.h" #include "lwip/raw.h" #include "lwip/tcpip.h" #include "lwip/inet.h" #include "lwip/pbuf.h" #include "lwip/timeouts.h" #include "string.h" #include <stdint.h> static struct netconn *conn, *newconn; static struct netbuf *buf; static ip_addr_t *addr; static unsigned short port; char msg[100]; char smsg[200]; ETH_HandleTypeDef heth; После инициализации в main или DefaultTask вызываем tcpserver_init(); static void tcp_thread(void *arg) { err_t err, accept_err, recv_error; conn = netconn_new(NETCONN_TCP); if (conn != NULL) { err = netconn_bind(conn, IP_ADDR_ANY, 7); if (err == ERR_OK) { netconn_listen(conn); while (1) { accept_err = netconn_accept(conn, &newconn); if (accept_err == ERR_OK) { // Send a welcome message to the client const char *welcome_msg = "Welcome to the echo server!\n"; netconn_write(newconn, welcome_msg, strlen(welcome_msg), NETCONN_COPY); while (netconn_recv(newconn, &buf) == ERR_OK) { addr = netbuf_fromaddr(buf); // get the address of the client port = netbuf_fromport(buf); // get the Port of the client do { strncpy(msg, buf->p->payload, buf->p->len); // get the message from the client // Respond with the received message int len = sprintf(smsg, "\"%s\" was sent by the Server\n", msg); netconn_write(newconn, smsg, len, NETCONN_COPY); // send the message back to the client } while (netbuf_next(buf) > 0); netbuf_delete(buf); } netconn_close(newconn); netconn_delete(newconn); } } } else { netconn_delete(conn); } } } void tcpserver_init(void) { sys_thread_new("tcp_thread", tcp_thread, NULL, DEFAULT_THREAD_STACKSIZE, osPriorityNormal); } - Регистр WUCSR тоже полезно прочитать. Там содержатся начальные установки (как писали выше). Вот значение всех моих регистров последовательно согласно datasheet: Спойлер 0000000010001000 1011010000011110 1110000000000000 1000110010000011 1000011110000000 1000011110110011 1111011000000000 1000000000000100 0000000000000010 0000000000000000 0000000000000000 1000001000000000 0100000000000000 0000011100000110 1011100111011001 0000000000000000 0000000000000000 0101000000000000 0000000000001010 0001001100000000 0000000000000000 0001101000001000 0001000100000000 0000000000000010 0000000000000000 0000000000000000 0000000000000000 0000000000000000 1111111111111111 1111111111111111 1111111111111111 0000000000001000 0000000000000000 0000000000000000 0001000100000000 0000000000000010 0000000000000001 0110001110000000 0101001100000000 0000000000000000 0000000000000000 - Осциллограммы всех пинов приложу ниже (чтобы примерно ориентироваться, что должно быть) + отдельно осциллограммы пинов TXD при отправке фрейма, о котором писал выше. Вроде все описал, единственное, надо бы все-таки провести линии TXD и RXD согласно технической документации согласовав по длине и сопротивлению. LAN8742_QFN_Rev_A_Routing_Checklist.pdf LAN8742A QFN Rev A Schematic Checklist.pdf Quote Share this post Link to post Share on other sites More sharing options...