1
2 /**
3 * @file xmc_ecat.c
4 * @date 2017-04-27
5 *
6 * @cond
7 *********************************************************************************************************************
8 * XMClib v2.1.24 - XMC Peripheral Driver Library
9 *
10 * Copyright (c) 2015-2019, Infineon Technologies AG
11 * All rights reserved.
12 *
13 * Redistribution and use in source and binary forms, with or without modification,are permitted provided that the
14 * following conditions are met:
15 *
16 * Redistributions of source code must retain the above copyright notice, this list of conditions and the following
17 * disclaimer.
18 *
19 * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following
20 * disclaimer in the documentation and/or other materials provided with the distribution.
21 *
22 * Neither the name of the copyright holders nor the names of its contributors may be used to endorse or promote
23 * products derived from this software without specific prior written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
26 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
27 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
29 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
30 * WHETHER IN CONTRACT, STRICT LIABILITY,OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 *
33 * To improve the quality of the software, users are encouraged to share modifications, enhancements or bug fixes with
34 * Infineon Technologies AG dave@infineon.com).
35 *********************************************************************************************************************
36 *
37 * Change History
38 * --------------
39 *
40 * 2015-10-21:
41 * - Initial Version
42 *
43 * 2015-12-27:
44 * - Add clock gating control in enable/disable APIs
45 *
46 * 2017-04-27:
47 * - Changed XMC_ECAT_ReadPhy() and XMC_ECAT_WritePhy() to release the MII access and check that the master enables take over of MII management control
48 *
49 * @endcond
50 */
51
52 /*******************************************************************************
53 * HEADER FILES
54 *******************************************************************************/
55
56 #include <xmc_ecat.h>
57
58 #if defined (ECAT0)
59
60 #include <xmc_scu.h>
61
62 /*******************************************************************************
63 * MACROS
64 *******************************************************************************/
65
66 /*******************************************************************************
67 * API IMPLEMENTATION
68 *******************************************************************************/
69 /* The function defines the access state to the MII management for the PDI interface*/
XMC_ECAT_lRequestPhyAccessToMII(void)70 __STATIC_INLINE void XMC_ECAT_lRequestPhyAccessToMII(void)
71 {
72 ECAT0->MII_PDI_ACS_STATE = 0x1;
73 }
74
XMC_ECAT_lReleasePhyAccessToMII(void)75 __STATIC_INLINE void XMC_ECAT_lReleasePhyAccessToMII(void)
76 {
77 ECAT0->MII_PDI_ACS_STATE = 0x0;
78 }
79
80 /* EtherCAT module clock ungating and deassert reset API (Enables ECAT) */
XMC_ECAT_Enable(void)81 void XMC_ECAT_Enable(void)
82 {
83 XMC_SCU_CLOCK_UngatePeripheralClock(XMC_SCU_PERIPHERAL_CLOCK_ECAT0);
84 XMC_SCU_RESET_DeassertPeripheralReset(XMC_SCU_PERIPHERAL_RESET_ECAT0);
85
86 while (XMC_SCU_RESET_IsPeripheralResetAsserted(XMC_SCU_PERIPHERAL_RESET_ECAT0) == true){}
87 }
88
89 /* EtherCAT module clock gating and assert reset API (Disables ECAT)*/
XMC_ECAT_Disable(void)90 void XMC_ECAT_Disable(void)
91 {
92 XMC_SCU_RESET_AssertPeripheralReset(XMC_SCU_PERIPHERAL_RESET_ECAT0);
93 while (XMC_SCU_RESET_IsPeripheralResetAsserted(XMC_SCU_PERIPHERAL_RESET_ECAT0) == false){}
94
95 XMC_SCU_CLOCK_GatePeripheralClock(XMC_SCU_PERIPHERAL_CLOCK_ECAT0);
96 }
97
98 /* EtherCAT initialization function */
XMC_ECAT_Init(XMC_ECAT_CONFIG_t * const config)99 void XMC_ECAT_Init(XMC_ECAT_CONFIG_t *const config)
100 {
101 XMC_ECAT_Enable();
102
103 /* The process memory is not accessible until the ESC Configuration Area is loaded successfully. */
104
105 /* words 0x0-0x3 */
106 ECAT0->EEP_DATA[0U] = config->dword[0U];
107 ECAT0->EEP_DATA[1U] = config->dword[1U];
108 ECAT0->EEP_CONT_STAT |= (uint16_t)((uint16_t)0x4U << (uint16_t)ECAT_EEP_CONT_STAT_CMD_REG_Pos);
109
110 /* words 0x4-0x7 */
111 ECAT0->EEP_DATA[0U] = config->dword[2U];
112 ECAT0->EEP_DATA[1U] = config->dword[3U];
113 ECAT0->EEP_CONT_STAT |= (uint16_t)((uint16_t)0x4U << (uint16_t)ECAT_EEP_CONT_STAT_CMD_REG_Pos);
114
115 while (ECAT0->EEP_CONT_STAT & ECAT_EEP_CONT_STAT_L_STAT_Msk)
116 {
117 /* Wait until the EEPROM_Loaded signal is active */
118 }
119
120 }
121
122 /* EtherCAT application event enable API */
XMC_ECAT_EnableEvent(uint32_t event)123 void XMC_ECAT_EnableEvent(uint32_t event)
124 {
125 ECAT0->AL_EVENT_MASK |= event;
126 }
127 /* EtherCAT application event disable API */
XMC_ECAT_DisableEvent(uint32_t event)128 void XMC_ECAT_DisableEvent(uint32_t event)
129 {
130 ECAT0->AL_EVENT_MASK &= ~event;
131 }
132
133 /* EtherCAT application event status reading API */
XMC_ECAT_GetEventStatus(void)134 uint32_t XMC_ECAT_GetEventStatus(void)
135 {
136 return (ECAT0->AL_EVENT_REQ);
137 }
138
139 /* EtherCAT SyncManager channel disable function*/
XMC_ECAT_DisableSyncManChannel(const uint8_t channel)140 void XMC_ECAT_DisableSyncManChannel(const uint8_t channel)
141 {
142 ((ECAT0_SM_Type *)(void*)((uint8_t *)(void*)ECAT0_SM0 + (channel * 8U)))->SM_PDI_CTR |= 0x1U;
143 }
144
145 /* EtherCAT SyncManager channel enable function*/
XMC_ECAT_EnableSyncManChannel(const uint8_t channel)146 void XMC_ECAT_EnableSyncManChannel(const uint8_t channel)
147 {
148 ((ECAT0_SM_Type *)(void*)((uint8_t *)(void*)ECAT0_SM0 + (channel * 8U)))->SM_PDI_CTR &= (uint8_t)(~0x1U);
149 }
150
151
152 /* EtherCAT PHY register read function*/
XMC_ECAT_ReadPhy(uint8_t phy_addr,uint8_t reg_addr,uint16_t * data)153 XMC_ECAT_STATUS_t XMC_ECAT_ReadPhy(uint8_t phy_addr, uint8_t reg_addr, uint16_t *data)
154 {
155 XMC_ECAT_STATUS_t status;
156
157 if ((ECAT0->MII_ECAT_ACS_STATE != 0) || ((ECAT0->MII_PDI_ACS_STATE & ECAT_MII_PDI_ACS_STATE_FORCE_PDI_ACS_S_Msk) != 0))
158 {
159 status = XMC_ECAT_STATUS_ERROR;
160 }
161 else
162 {
163 XMC_ECAT_lRequestPhyAccessToMII();
164
165 ECAT0->MII_PHY_ADR = phy_addr;
166 ECAT0->MII_PHY_REG_ADR = reg_addr;
167
168 ECAT0->MII_CONT_STAT = 0x0100U; /* read instruction */
169 while ((ECAT0->MII_CONT_STAT & ECAT_MII_CONT_STAT_BUSY_Msk) != 0U){}
170
171 if ((ECAT0->MII_CONT_STAT & ECAT_MII_CONT_STAT_ERROR_Msk) != 0U)
172 {
173 ECAT0->MII_CONT_STAT = 0; /* Clear error */
174 status = XMC_ECAT_STATUS_ERROR;
175 }
176 else
177 {
178 *data = (uint16_t)ECAT0->MII_PHY_DATA;
179 status = XMC_ECAT_STATUS_OK;
180 }
181
182 XMC_ECAT_lReleasePhyAccessToMII();
183 }
184
185 return status;
186 }
187
188 /* EtherCAT PHY register write function*/
XMC_ECAT_WritePhy(uint8_t phy_addr,uint8_t reg_addr,uint16_t data)189 XMC_ECAT_STATUS_t XMC_ECAT_WritePhy(uint8_t phy_addr, uint8_t reg_addr, uint16_t data)
190 {
191 XMC_ECAT_STATUS_t status;
192
193 if ((ECAT0->MII_ECAT_ACS_STATE != 0) || ((ECAT0->MII_PDI_ACS_STATE & ECAT_MII_PDI_ACS_STATE_FORCE_PDI_ACS_S_Msk) != 0))
194 {
195 status = XMC_ECAT_STATUS_ERROR;
196 }
197 else
198 {
199 XMC_ECAT_lRequestPhyAccessToMII();
200
201 ECAT0->MII_PHY_ADR = phy_addr;
202 ECAT0->MII_PHY_REG_ADR = reg_addr;
203 ECAT0->MII_PHY_DATA = data;
204
205 ECAT0->MII_CONT_STAT = 0x0200U; /* write instruction */
206 while ((ECAT0->MII_CONT_STAT & ECAT_MII_CONT_STAT_BUSY_Msk) != 0U){}
207
208 if ((ECAT0->MII_CONT_STAT & ECAT_MII_CONT_STAT_ERROR_Msk) != 0U)
209 {
210 ECAT0->MII_CONT_STAT = 0; /* Clear error */
211 status = XMC_ECAT_STATUS_ERROR;
212 }
213 else
214 {
215 status = XMC_ECAT_STATUS_OK;
216 }
217
218 XMC_ECAT_lReleasePhyAccessToMII();
219 }
220
221 return status;
222 }
223
224 #endif
225