1 /*
2 * Copyright (c) 2024 HPMicro
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 *
6 */
7
8 #include "hpm_esc_drv.h"
9
10 #ifndef HPM_ESC_DRV_DEFAULT_RETRY_COUNT
11 #define HPM_ESC_DRV_DEFAULT_RETRY_COUNT (0xA0000000U)
12 #endif
13
esc_mdio_read(ESC_Type * ptr,uint8_t phy_addr,uint8_t reg_addr,uint16_t * data)14 hpm_stat_t esc_mdio_read(ESC_Type *ptr, uint8_t phy_addr, uint8_t reg_addr, uint16_t *data)
15 {
16 uint32_t retry;
17
18 ptr->MIIM_PDI_ACC_STAT = 1; /* PDI access MII management interface */
19
20 /* wait for MII idle */
21 retry = 0;
22 while ((ptr->MII_MNG_CS & ESC_MII_MNG_CS_BUSY_MASK) != 0) {
23 if (retry > HPM_ESC_DRV_DEFAULT_RETRY_COUNT) {
24 break;
25 }
26 retry++;
27 }
28 if (retry > HPM_ESC_DRV_DEFAULT_RETRY_COUNT) {
29 return status_timeout;
30 }
31
32 /* set PHY address and register address */
33 ptr->PHY_ADDR = phy_addr;
34 ptr->PHY_REG_ADDR = reg_addr;
35
36 /* read command */
37 ptr->MII_MNG_CS = (ptr->MII_MNG_CS & ~ESC_MII_MNG_CS_CMD_MASK) | ESC_MII_MNG_CS_CMD_SET(1);
38
39 /* wait command done */
40 retry = 0;
41 while ((ptr->MII_MNG_CS & ESC_MII_MNG_CS_BUSY_MASK) != 0) {
42 if (retry > HPM_ESC_DRV_DEFAULT_RETRY_COUNT) {
43 break;
44 }
45 retry++;
46 }
47 if (retry > HPM_ESC_DRV_DEFAULT_RETRY_COUNT) {
48 return status_timeout;
49 }
50
51 /* check error status */
52 if ((ptr->MII_MNG_CS & ESC_MII_MNG_CS_CMD_ERR_MASK) != 0) {
53 return status_fail;
54 }
55
56 /* check error status */
57 if ((ptr->MII_MNG_CS & ESC_MII_MNG_CS_CMD_ERR_MASK) != 0) {
58 return status_fail;
59 }
60
61 *data = ptr->PHY_DATA;
62
63 return status_success;
64 }
65
esc_mdio_write(ESC_Type * ptr,uint8_t phy_addr,uint8_t reg_addr,uint16_t data)66 hpm_stat_t esc_mdio_write(ESC_Type *ptr, uint8_t phy_addr, uint8_t reg_addr, uint16_t data)
67 {
68 uint32_t retry;
69
70 ptr->MIIM_PDI_ACC_STAT = 1; /* PDI access MII management interface */
71
72 /* wait for MII idle */
73 retry = 0;
74 while ((ptr->MII_MNG_CS & ESC_MII_MNG_CS_BUSY_MASK) != 0) {
75 if (retry > HPM_ESC_DRV_DEFAULT_RETRY_COUNT) {
76 break;
77 }
78 retry++;
79 }
80 if (retry > HPM_ESC_DRV_DEFAULT_RETRY_COUNT) {
81 return status_timeout;
82 }
83
84
85 /* set PHY address, register address and register value */
86 ptr->PHY_ADDR = phy_addr;
87 ptr->PHY_REG_ADDR = reg_addr;
88 ptr->PHY_DATA = data;
89
90 /* write command */
91 ptr->MII_MNG_CS = (ptr->MII_MNG_CS & ~ESC_MII_MNG_CS_CMD_MASK) | ESC_MII_MNG_CS_WEN_MASK | ESC_MII_MNG_CS_CMD_SET(2);
92
93 /* wait command done */
94 retry = 0;
95 while ((ptr->MII_MNG_CS & ESC_MII_MNG_CS_BUSY_MASK) != 0) {
96 if (retry > HPM_ESC_DRV_DEFAULT_RETRY_COUNT) {
97 break;
98 }
99 retry++;
100 }
101 if (retry > HPM_ESC_DRV_DEFAULT_RETRY_COUNT) {
102 return status_timeout;
103 }
104
105 /* check error status */
106 if ((ptr->MII_MNG_CS & ESC_MII_MNG_CS_CMD_ERR_MASK) != 0) {
107 return status_fail;
108 }
109
110 /* check error status */
111 if ((ptr->MII_MNG_CS & ESC_MII_MNG_CS_CMD_ERR_MASK) != 0) {
112 return status_fail;
113 }
114
115 return status_success;
116 }
117
118 /* Loding ESC EEPROM, EtherCAT communication is possible even if the EEPROM is blank */
esc_check_eeprom_loading(ESC_Type * ptr)119 hpm_stat_t esc_check_eeprom_loading(ESC_Type *ptr)
120 {
121 hpm_stat_t stat = status_success;
122 uint32_t retry = 0;
123
124 while (1) {
125 /* 0x110 bit0 eeprom load correctly */
126 if ((ptr->ESC_DL_STAT & ESC_ESC_DL_STAT_EPLC_MASK) == ESC_ESC_DL_STAT_EPLC_MASK) {
127 stat = status_success; /* Loading successful, PDI operations */
128 break;
129 }
130
131 /* 0x502 bit13 ack or cmd error */
132 if ((ptr->EEPROM_CTRL_STAT & ESC_EEPROM_CTRL_STAT_ERR_ACK_CMD_MASK) == ESC_EEPROM_CTRL_STAT_ERR_ACK_CMD_MASK) { /* ACMDERR = 1 */
133 stat = status_esc_eeprom_ack_error; /* I2C bus error */
134 break;
135 } else {
136 if ((ptr->EEPROM_CTRL_STAT & ESC_EEPROM_CTRL_STAT_CKSM_ERR_MASK) == ESC_EEPROM_CTRL_STAT_CKSM_ERR_MASK) { /* ACMDERR,CKSUMERR = 01 */
137 stat = status_esc_eeprom_checksum_error; /* EEPROM is loaded, but it is blank and cause checksum error */
138 break;
139 }
140 }
141
142 if (retry > HPM_ESC_DRV_DEFAULT_RETRY_COUNT) {
143 stat = status_timeout;
144 break;
145 }
146 retry++;
147 }
148
149 return stat;
150 }
151