1 /** 2 ****************************************************************************** 3 * @file stm32n6xx_hal_pcd.h 4 * @author MCD Application Team 5 * @brief Header file of PCD HAL module. 6 ****************************************************************************** 7 * @attention 8 * 9 * Copyright (c) 2023 STMicroelectronics. 10 * All rights reserved. 11 * 12 * This software is licensed under terms that can be found in the LICENSE file 13 * in the root directory of this software component. 14 * If no LICENSE file comes with this software, it is provided AS-IS. 15 * 16 ****************************************************************************** 17 */ 18 19 /* Define to prevent recursive inclusion -------------------------------------*/ 20 #ifndef STM32N6xx_HAL_PCD_H 21 #define STM32N6xx_HAL_PCD_H 22 23 #ifdef __cplusplus 24 extern "C" { 25 #endif 26 27 /* Includes ------------------------------------------------------------------*/ 28 #include "stm32n6xx_ll_usb.h" 29 30 #if defined (USB1_OTG_HS) || defined (USB2_OTG_HS) 31 32 /** @addtogroup STM32N6xx_HAL_Driver 33 * @{ 34 */ 35 36 /** @addtogroup PCD 37 * @{ 38 */ 39 40 /* Exported types ------------------------------------------------------------*/ 41 /** @defgroup PCD_Exported_Types PCD Exported Types 42 * @{ 43 */ 44 45 /** 46 * @brief PCD State structure definition 47 */ 48 typedef enum 49 { 50 HAL_PCD_STATE_RESET = 0x00, 51 HAL_PCD_STATE_READY = 0x01, 52 HAL_PCD_STATE_ERROR = 0x02, 53 HAL_PCD_STATE_BUSY = 0x03, 54 HAL_PCD_STATE_TIMEOUT = 0x04 55 } PCD_StateTypeDef; 56 57 /* Device LPM suspend state */ 58 typedef enum 59 { 60 LPM_L0 = 0x00, /* on */ 61 LPM_L1 = 0x01, /* LPM L1 sleep */ 62 LPM_L2 = 0x02, /* suspend */ 63 LPM_L3 = 0x03, /* off */ 64 } PCD_LPM_StateTypeDef; 65 66 typedef enum 67 { 68 PCD_LPM_L0_ACTIVE = 0x00, /* on */ 69 PCD_LPM_L1_ACTIVE = 0x01, /* LPM L1 sleep */ 70 } PCD_LPM_MsgTypeDef; 71 72 typedef enum 73 { 74 PCD_BCD_ERROR = 0xFF, 75 PCD_BCD_CONTACT_DETECTION = 0xFE, 76 PCD_BCD_STD_DOWNSTREAM_PORT = 0xFD, 77 PCD_BCD_CHARGING_DOWNSTREAM_PORT = 0xFC, 78 PCD_BCD_DEDICATED_CHARGING_PORT = 0xFB, 79 PCD_BCD_DISCOVERY_COMPLETED = 0x00, 80 81 } PCD_BCD_MsgTypeDef; 82 83 #if defined (USB1_OTG_HS) || defined (USB2_OTG_HS) 84 typedef USB_OTG_GlobalTypeDef PCD_TypeDef; 85 typedef USB_OTG_CfgTypeDef PCD_InitTypeDef; 86 typedef USB_OTG_EPTypeDef PCD_EPTypeDef; 87 #endif /* defined (USB1_OTG_HS) || defined (USB2_OTG_HS) */ 88 89 /** 90 * @brief PCD Handle Structure definition 91 */ 92 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) 93 typedef struct __PCD_HandleTypeDef 94 #else 95 typedef struct 96 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ 97 { 98 PCD_TypeDef *Instance; /*!< Register base address */ 99 PCD_InitTypeDef Init; /*!< PCD required parameters */ 100 __IO uint8_t USB_Address; /*!< USB Address */ 101 PCD_EPTypeDef IN_ep[16]; /*!< IN endpoint parameters */ 102 PCD_EPTypeDef OUT_ep[16]; /*!< OUT endpoint parameters */ 103 HAL_LockTypeDef Lock; /*!< PCD peripheral status */ 104 __IO PCD_StateTypeDef State; /*!< PCD communication state */ 105 __IO uint32_t ErrorCode; /*!< PCD Error code */ 106 uint32_t Setup[12]; /*!< Setup packet buffer */ 107 PCD_LPM_StateTypeDef LPM_State; /*!< LPM State */ 108 uint32_t BESL; 109 uint32_t FrameNumber; /*!< Store Current Frame number */ 110 111 112 uint32_t lpm_active; /*!< Enable or disable the Link Power Management . 113 This parameter can be set to ENABLE or DISABLE */ 114 115 uint32_t battery_charging_active; /*!< Enable or disable Battery charging. 116 This parameter can be set to ENABLE or DISABLE */ 117 void *pData; /*!< Pointer to upper stack Handler */ 118 119 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) 120 void (* SOFCallback)(struct __PCD_HandleTypeDef *hpcd); /*!< USB OTG PCD SOF callback */ 121 void (* SetupStageCallback)(struct __PCD_HandleTypeDef *hpcd); /*!< USB OTG PCD Setup Stage callback */ 122 void (* ResetCallback)(struct __PCD_HandleTypeDef *hpcd); /*!< USB OTG PCD Reset callback */ 123 void (* SuspendCallback)(struct __PCD_HandleTypeDef *hpcd); /*!< USB OTG PCD Suspend callback */ 124 void (* ResumeCallback)(struct __PCD_HandleTypeDef *hpcd); /*!< USB OTG PCD Resume callback */ 125 void (* ConnectCallback)(struct __PCD_HandleTypeDef *hpcd); /*!< USB OTG PCD Connect callback */ 126 void (* DisconnectCallback)(struct __PCD_HandleTypeDef *hpcd); /*!< USB OTG PCD Disconnect callback */ 127 128 void (* DataOutStageCallback)(struct __PCD_HandleTypeDef *hpcd, uint8_t epnum); /*!< USB OTG PCD Data OUT Stage callback */ 129 void (* DataInStageCallback)(struct __PCD_HandleTypeDef *hpcd, uint8_t epnum); /*!< USB OTG PCD Data IN Stage callback */ 130 void (* ISOOUTIncompleteCallback)(struct __PCD_HandleTypeDef *hpcd, uint8_t epnum); /*!< USB OTG PCD ISO OUT Incomplete callback */ 131 void (* ISOINIncompleteCallback)(struct __PCD_HandleTypeDef *hpcd, uint8_t epnum); /*!< USB OTG PCD ISO IN Incomplete callback */ 132 void (* BCDCallback)(struct __PCD_HandleTypeDef *hpcd, PCD_BCD_MsgTypeDef msg); /*!< USB OTG PCD BCD callback */ 133 void (* LPMCallback)(struct __PCD_HandleTypeDef *hpcd, PCD_LPM_MsgTypeDef msg); /*!< USB OTG PCD LPM callback */ 134 135 void (* MspInitCallback)(struct __PCD_HandleTypeDef *hpcd); /*!< USB OTG PCD Msp Init callback */ 136 void (* MspDeInitCallback)(struct __PCD_HandleTypeDef *hpcd); /*!< USB OTG PCD Msp DeInit callback */ 137 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ 138 } PCD_HandleTypeDef; 139 140 /** 141 * @} 142 */ 143 144 /* Include PCD HAL Extended module */ 145 #include "stm32n6xx_hal_pcd_ex.h" 146 147 /* Exported constants --------------------------------------------------------*/ 148 /** @defgroup PCD_Exported_Constants PCD Exported Constants 149 * @{ 150 */ 151 152 /** @defgroup PCD_Speed PCD Speed 153 * @{ 154 */ 155 #define PCD_SPEED_HIGH USBD_HS_SPEED 156 #define PCD_SPEED_HIGH_IN_FULL USBD_HSINFS_SPEED 157 #define PCD_SPEED_FULL USBD_FS_SPEED 158 /** 159 * @} 160 */ 161 162 /** @defgroup PCD_PHY_Module PCD PHY Module 163 * @{ 164 */ 165 #define PCD_PHY_ULPI 1U 166 #define PCD_PHY_EMBEDDED 2U 167 #define PCD_PHY_UTMI 3U 168 /** 169 * @} 170 */ 171 172 /** @defgroup PCD_Error_Code_definition PCD Error Code definition 173 * @brief PCD Error Code definition 174 * @{ 175 */ 176 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) 177 #define HAL_PCD_ERROR_INVALID_CALLBACK (0x00000010U) /*!< Invalid Callback error */ 178 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ 179 180 /** 181 * @} 182 */ 183 184 /** 185 * @} 186 */ 187 188 /* Exported macros -----------------------------------------------------------*/ 189 /** @defgroup PCD_Exported_Macros PCD Exported Macros 190 * @brief macros to handle interrupts and specific clock configurations 191 * @{ 192 */ 193 #define __HAL_PCD_ENABLE(__HANDLE__) (void)USB_EnableGlobalInt ((__HANDLE__)->Instance) 194 #define __HAL_PCD_DISABLE(__HANDLE__) (void)USB_DisableGlobalInt ((__HANDLE__)->Instance) 195 196 #define __HAL_PCD_GET_FLAG(__HANDLE__, __INTERRUPT__) \ 197 ((USB_ReadInterrupts((__HANDLE__)->Instance) & (__INTERRUPT__)) == (__INTERRUPT__)) 198 199 #if defined (USB1_OTG_HS) || defined (USB2_OTG_HS) 200 #define __HAL_PCD_CLEAR_FLAG(__HANDLE__, __INTERRUPT__) (((__HANDLE__)->Instance->GINTSTS) &= (__INTERRUPT__)) 201 #define __HAL_PCD_IS_INVALID_INTERRUPT(__HANDLE__) (USB_ReadInterrupts((__HANDLE__)->Instance) == 0U) 202 203 #define __HAL_PCD_UNGATE_PHYCLOCK(__HANDLE__) \ 204 *(__IO uint32_t *)((uint32_t)((__HANDLE__)->Instance) + USB_OTG_PCGCCTL_BASE) &= ~(USB_OTG_PCGCCTL_STOPCLK) 205 206 #define __HAL_PCD_GATE_PHYCLOCK(__HANDLE__) \ 207 *(__IO uint32_t *)((uint32_t)((__HANDLE__)->Instance) + USB_OTG_PCGCCTL_BASE) |= USB_OTG_PCGCCTL_STOPCLK 208 209 #define __HAL_PCD_IS_PHY_SUSPENDED(__HANDLE__) \ 210 ((*(__IO uint32_t *)((uint32_t)((__HANDLE__)->Instance) + USB_OTG_PCGCCTL_BASE)) & 0x10U) 211 #endif /* defined (USB1_OTG_HS) || defined (USB2_OTG_HS) */ 212 213 214 /** 215 * @} 216 */ 217 218 /* Exported functions --------------------------------------------------------*/ 219 /** @addtogroup PCD_Exported_Functions PCD Exported Functions 220 * @{ 221 */ 222 223 /* Initialization/de-initialization functions ********************************/ 224 /** @addtogroup PCD_Exported_Functions_Group1 Initialization and de-initialization functions 225 * @{ 226 */ 227 HAL_StatusTypeDef HAL_PCD_Init(PCD_HandleTypeDef *hpcd); 228 HAL_StatusTypeDef HAL_PCD_DeInit(PCD_HandleTypeDef *hpcd); 229 void HAL_PCD_MspInit(PCD_HandleTypeDef *hpcd); 230 void HAL_PCD_MspDeInit(PCD_HandleTypeDef *hpcd); 231 232 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) 233 /** @defgroup HAL_PCD_Callback_ID_enumeration_definition HAL USB OTG PCD Callback ID enumeration definition 234 * @brief HAL USB OTG PCD Callback ID enumeration definition 235 * @{ 236 */ 237 typedef enum 238 { 239 HAL_PCD_SOF_CB_ID = 0x01, /*!< USB PCD SOF callback ID */ 240 HAL_PCD_SETUPSTAGE_CB_ID = 0x02, /*!< USB PCD Setup Stage callback ID */ 241 HAL_PCD_RESET_CB_ID = 0x03, /*!< USB PCD Reset callback ID */ 242 HAL_PCD_SUSPEND_CB_ID = 0x04, /*!< USB PCD Suspend callback ID */ 243 HAL_PCD_RESUME_CB_ID = 0x05, /*!< USB PCD Resume callback ID */ 244 HAL_PCD_CONNECT_CB_ID = 0x06, /*!< USB PCD Connect callback ID */ 245 HAL_PCD_DISCONNECT_CB_ID = 0x07, /*!< USB PCD Disconnect callback ID */ 246 247 HAL_PCD_MSPINIT_CB_ID = 0x08, /*!< USB PCD MspInit callback ID */ 248 HAL_PCD_MSPDEINIT_CB_ID = 0x09 /*!< USB PCD MspDeInit callback ID */ 249 250 } HAL_PCD_CallbackIDTypeDef; 251 /** 252 * @} 253 */ 254 255 /** @defgroup HAL_PCD_Callback_pointer_definition HAL USB OTG PCD Callback pointer definition 256 * @brief HAL USB OTG PCD Callback pointer definition 257 * @{ 258 */ 259 260 typedef void (*pPCD_CallbackTypeDef)(PCD_HandleTypeDef *hpcd); /*!< pointer to a common USB OTG PCD callback function */ 261 typedef void (*pPCD_DataOutStageCallbackTypeDef)(PCD_HandleTypeDef *hpcd, uint8_t epnum); /*!< pointer to USB OTG PCD Data OUT Stage callback */ 262 typedef void (*pPCD_DataInStageCallbackTypeDef)(PCD_HandleTypeDef *hpcd, uint8_t epnum); /*!< pointer to USB OTG PCD Data IN Stage callback */ 263 typedef void (*pPCD_IsoOutIncpltCallbackTypeDef)(PCD_HandleTypeDef *hpcd, uint8_t epnum); /*!< pointer to USB OTG PCD ISO OUT Incomplete callback */ 264 typedef void (*pPCD_IsoInIncpltCallbackTypeDef)(PCD_HandleTypeDef *hpcd, uint8_t epnum); /*!< pointer to USB OTG PCD ISO IN Incomplete callback */ 265 typedef void (*pPCD_LpmCallbackTypeDef)(PCD_HandleTypeDef *hpcd, PCD_LPM_MsgTypeDef msg); /*!< pointer to USB OTG PCD LPM callback */ 266 typedef void (*pPCD_BcdCallbackTypeDef)(PCD_HandleTypeDef *hpcd, PCD_BCD_MsgTypeDef msg); /*!< pointer to USB OTG PCD BCD callback */ 267 268 /** 269 * @} 270 */ 271 272 HAL_StatusTypeDef HAL_PCD_RegisterCallback(PCD_HandleTypeDef *hpcd, HAL_PCD_CallbackIDTypeDef CallbackID, 273 pPCD_CallbackTypeDef pCallback); 274 275 HAL_StatusTypeDef HAL_PCD_UnRegisterCallback(PCD_HandleTypeDef *hpcd, HAL_PCD_CallbackIDTypeDef CallbackID); 276 277 HAL_StatusTypeDef HAL_PCD_RegisterDataOutStageCallback(PCD_HandleTypeDef *hpcd, 278 pPCD_DataOutStageCallbackTypeDef pCallback); 279 280 HAL_StatusTypeDef HAL_PCD_UnRegisterDataOutStageCallback(PCD_HandleTypeDef *hpcd); 281 282 HAL_StatusTypeDef HAL_PCD_RegisterDataInStageCallback(PCD_HandleTypeDef *hpcd, 283 pPCD_DataInStageCallbackTypeDef pCallback); 284 285 HAL_StatusTypeDef HAL_PCD_UnRegisterDataInStageCallback(PCD_HandleTypeDef *hpcd); 286 287 HAL_StatusTypeDef HAL_PCD_RegisterIsoOutIncpltCallback(PCD_HandleTypeDef *hpcd, 288 pPCD_IsoOutIncpltCallbackTypeDef pCallback); 289 290 HAL_StatusTypeDef HAL_PCD_UnRegisterIsoOutIncpltCallback(PCD_HandleTypeDef *hpcd); 291 292 HAL_StatusTypeDef HAL_PCD_RegisterIsoInIncpltCallback(PCD_HandleTypeDef *hpcd, 293 pPCD_IsoInIncpltCallbackTypeDef pCallback); 294 295 HAL_StatusTypeDef HAL_PCD_UnRegisterIsoInIncpltCallback(PCD_HandleTypeDef *hpcd); 296 297 HAL_StatusTypeDef HAL_PCD_RegisterBcdCallback(PCD_HandleTypeDef *hpcd, pPCD_BcdCallbackTypeDef pCallback); 298 HAL_StatusTypeDef HAL_PCD_UnRegisterBcdCallback(PCD_HandleTypeDef *hpcd); 299 300 HAL_StatusTypeDef HAL_PCD_RegisterLpmCallback(PCD_HandleTypeDef *hpcd, pPCD_LpmCallbackTypeDef pCallback); 301 HAL_StatusTypeDef HAL_PCD_UnRegisterLpmCallback(PCD_HandleTypeDef *hpcd); 302 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ 303 /** 304 * @} 305 */ 306 307 /* I/O operation functions ***************************************************/ 308 /* Non-Blocking mode: Interrupt */ 309 /** @addtogroup PCD_Exported_Functions_Group2 Input and Output operation functions 310 * @{ 311 */ 312 HAL_StatusTypeDef HAL_PCD_Start(PCD_HandleTypeDef *hpcd); 313 HAL_StatusTypeDef HAL_PCD_Stop(PCD_HandleTypeDef *hpcd); 314 void HAL_PCD_IRQHandler(PCD_HandleTypeDef *hpcd); 315 316 void HAL_PCD_SOFCallback(PCD_HandleTypeDef *hpcd); 317 void HAL_PCD_SetupStageCallback(PCD_HandleTypeDef *hpcd); 318 void HAL_PCD_ResetCallback(PCD_HandleTypeDef *hpcd); 319 void HAL_PCD_SuspendCallback(PCD_HandleTypeDef *hpcd); 320 void HAL_PCD_ResumeCallback(PCD_HandleTypeDef *hpcd); 321 void HAL_PCD_ConnectCallback(PCD_HandleTypeDef *hpcd); 322 void HAL_PCD_DisconnectCallback(PCD_HandleTypeDef *hpcd); 323 324 void HAL_PCD_DataOutStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum); 325 void HAL_PCD_DataInStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum); 326 void HAL_PCD_ISOOUTIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum); 327 void HAL_PCD_ISOINIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum); 328 /** 329 * @} 330 */ 331 332 /* Peripheral Control functions **********************************************/ 333 /** @addtogroup PCD_Exported_Functions_Group3 Peripheral Control functions 334 * @{ 335 */ 336 HAL_StatusTypeDef HAL_PCD_DevConnect(PCD_HandleTypeDef *hpcd); 337 HAL_StatusTypeDef HAL_PCD_DevDisconnect(PCD_HandleTypeDef *hpcd); 338 HAL_StatusTypeDef HAL_PCD_SetAddress(PCD_HandleTypeDef *hpcd, uint8_t address); 339 HAL_StatusTypeDef HAL_PCD_EP_Open(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint16_t ep_mps, uint8_t ep_type); 340 HAL_StatusTypeDef HAL_PCD_EP_Close(PCD_HandleTypeDef *hpcd, uint8_t ep_addr); 341 HAL_StatusTypeDef HAL_PCD_EP_Receive(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint8_t *pBuf, uint32_t len); 342 HAL_StatusTypeDef HAL_PCD_EP_Transmit(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint8_t *pBuf, uint32_t len); 343 HAL_StatusTypeDef HAL_PCD_EP_SetStall(PCD_HandleTypeDef *hpcd, uint8_t ep_addr); 344 HAL_StatusTypeDef HAL_PCD_EP_ClrStall(PCD_HandleTypeDef *hpcd, uint8_t ep_addr); 345 HAL_StatusTypeDef HAL_PCD_EP_Flush(PCD_HandleTypeDef *hpcd, uint8_t ep_addr); 346 HAL_StatusTypeDef HAL_PCD_EP_Abort(PCD_HandleTypeDef *hpcd, uint8_t ep_addr); 347 HAL_StatusTypeDef HAL_PCD_ActivateRemoteWakeup(PCD_HandleTypeDef *hpcd); 348 HAL_StatusTypeDef HAL_PCD_DeActivateRemoteWakeup(PCD_HandleTypeDef *hpcd); 349 #if defined (USB1_OTG_HS) || defined (USB2_OTG_HS) 350 HAL_StatusTypeDef HAL_PCD_SetTestMode(const PCD_HandleTypeDef *hpcd, uint8_t testmode); 351 #endif /* defined (USB1_OTG_HS) || defined (USB2_OTG_HS) */ 352 353 uint32_t HAL_PCD_EP_GetRxCount(PCD_HandleTypeDef const *hpcd, uint8_t ep_addr); 354 /** 355 * @} 356 */ 357 358 /* Peripheral State functions ************************************************/ 359 /** @addtogroup PCD_Exported_Functions_Group4 Peripheral State functions 360 * @{ 361 */ 362 PCD_StateTypeDef HAL_PCD_GetState(PCD_HandleTypeDef const *hpcd); 363 /** 364 * @} 365 */ 366 367 /** 368 * @} 369 */ 370 371 /* Private constants ---------------------------------------------------------*/ 372 /** @defgroup PCD_Private_Constants PCD Private Constants 373 * @{ 374 */ 375 /** 376 * @} 377 */ 378 379 #if defined (USB1_OTG_HS) || defined (USB2_OTG_HS) 380 #ifndef USB_OTG_DOEPINT_OTEPSPR 381 #define USB_OTG_DOEPINT_OTEPSPR (0x1UL << 5) /*!< Status Phase Received interrupt */ 382 #endif /* defined USB_OTG_DOEPINT_OTEPSPR */ 383 384 #ifndef USB_OTG_DOEPMSK_OTEPSPRM 385 #define USB_OTG_DOEPMSK_OTEPSPRM (0x1UL << 5) /*!< Setup Packet Received interrupt mask */ 386 #endif /* defined USB_OTG_DOEPMSK_OTEPSPRM */ 387 388 #ifndef USB_OTG_DOEPINT_NAK 389 #define USB_OTG_DOEPINT_NAK (0x1UL << 13) /*!< NAK interrupt */ 390 #endif /* defined USB_OTG_DOEPINT_NAK */ 391 392 #ifndef USB_OTG_DOEPMSK_NAKM 393 #define USB_OTG_DOEPMSK_NAKM (0x1UL << 13) /*!< OUT Packet NAK interrupt mask */ 394 #endif /* defined USB_OTG_DOEPMSK_NAKM */ 395 396 #ifndef USB_OTG_DOEPINT_STPKTRX 397 #define USB_OTG_DOEPINT_STPKTRX (0x1UL << 15) /*!< Setup Packet Received interrupt */ 398 #endif /* defined USB_OTG_DOEPINT_STPKTRX */ 399 400 #ifndef USB_OTG_DOEPMSK_NYETM 401 #define USB_OTG_DOEPMSK_NYETM (0x1UL << 14) /*!< Setup Packet Received interrupt mask */ 402 #endif /* defined USB_OTG_DOEPMSK_NYETM */ 403 #endif /* defined (USB1_OTG_HS) || defined (USB2_OTG_HS) */ 404 405 /* Private macros ------------------------------------------------------------*/ 406 /** @defgroup PCD_Private_Macros PCD Private Macros 407 * @{ 408 */ 409 410 /** 411 * @} 412 */ 413 414 /** 415 * @} 416 */ 417 418 /** 419 * @} 420 */ 421 #endif /* defined (USB1_OTG_HS) || defined (USB2_OTG_HS) */ 422 423 #ifdef __cplusplus 424 } 425 #endif 426 427 #endif /* STM32N6xx_HAL_PCD_H */ 428