stm32h7xx_hal_smbus.c 72 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050
  1. /**
  2. ******************************************************************************
  3. * @file stm32h7xx_hal_smbus.c
  4. * @author MCD Application Team
  5. * @version V1.0.0
  6. * @date 21-April-2017
  7. * @brief SMBUS HAL module driver.
  8. * This file provides firmware functions to manage the following
  9. * functionalities of the System Management Bus (SMBus) peripheral,
  10. * based on I2C principles of operation :
  11. * + Initialization and de-initialization functions
  12. * + IO operation functions
  13. * + Peripheral State and Errors functions
  14. *
  15. @verbatim
  16. ==============================================================================
  17. ##### How to use this driver #####
  18. ==============================================================================
  19. [..]
  20. The SMBUS HAL driver can be used as follows:
  21. (#) Declare a SMBUS_HandleTypeDef handle structure, for example:
  22. SMBUS_HandleTypeDef hsmbus;
  23. (#)Initialize the SMBUS low level resources by implementing the HAL_SMBUS_MspInit() API:
  24. (++) Enable the SMBUSx interface clock
  25. (++) SMBUS pins configuration
  26. (+++) Enable the clock for the SMBUS GPIOs
  27. (+++) Configure SMBUS pins as alternate function open-drain
  28. (++) NVIC configuration if you need to use interrupt process
  29. (+++) Configure the SMBUSx interrupt priority
  30. (+++) Enable the NVIC SMBUS IRQ Channel
  31. (#) Configure the Communication Clock Timing, Bus Timeout, Own Address1, Master Addressing Mode,
  32. Dual Addressing mode, Own Address2, Own Address2 Mask, General call, Nostretch mode,
  33. Peripheral mode and Packet Error Check mode in the hsmbus Init structure.
  34. (#) Initialize the SMBUS registers by calling the HAL_SMBUS_Init() API:
  35. (++) These API's configures also the low level Hardware GPIO, CLOCK, CORTEX...etc)
  36. by calling the customized HAL_SMBUS_MspInit(&hsmbus) API.
  37. (#) To check if target device is ready for communication, use the function HAL_SMBUS_IsDeviceReady()
  38. (#) For SMBUS IO operations, only one mode of operations is available within this driver
  39. *** Interrupt mode IO operation ***
  40. ===================================
  41. [..]
  42. (+) Transmit in master/host SMBUS mode an amount of data in non-blocking mode using HAL_SMBUS_Master_Transmit_IT()
  43. (++) At transmission end of transfer HAL_SMBUS_MasterTxCpltCallback() is executed and user can
  44. add his own code by customization of function pointer HAL_SMBUS_MasterTxCpltCallback()
  45. (+) Receive in master/host SMBUS mode an amount of data in non-blocking mode using HAL_SMBUS_Master_Receive_IT()
  46. (++) At reception end of transfer HAL_SMBUS_MasterRxCpltCallback() is executed and user can
  47. add his own code by customization of function pointer HAL_SMBUS_MasterRxCpltCallback()
  48. (+) Abort a master/host SMBUS process communication with Interrupt using HAL_SMBUS_Master_Abort_IT()
  49. (++) The associated previous transfer callback is called at the end of abort process
  50. (++) mean HAL_SMBUS_MasterTxCpltCallback() in case of previous state was master transmit
  51. (++) mean HAL_SMBUS_MasterRxCpltCallback() in case of previous state was master receive
  52. (+) Enable/disable the Address listen mode in slave/device or host/slave SMBUS mode
  53. using HAL_SMBUS_EnableListen_IT() HAL_SMBUS_DisableListen_IT()
  54. (++) When address slave/device SMBUS match, HAL_SMBUS_AddrCallback() is executed and user can
  55. add his own code to check the Address Match Code and the transmission direction request by master/host (Write/Read).
  56. (++) At Listen mode end HAL_SMBUS_ListenCpltCallback() is executed and user can
  57. add his own code by customization of function pointer HAL_SMBUS_ListenCpltCallback()
  58. (+) Transmit in slave/device SMBUS mode an amount of data in non-blocking mode using HAL_SMBUS_Slave_Transmit_IT()
  59. (++) At transmission end of transfer HAL_SMBUS_SlaveTxCpltCallback() is executed and user can
  60. add his own code by customization of function pointer HAL_SMBUS_SlaveTxCpltCallback()
  61. (+) Receive in slave/device SMBUS mode an amount of data in non-blocking mode using HAL_SMBUS_Slave_Receive_IT()
  62. (++) At reception end of transfer HAL_SMBUS_SlaveRxCpltCallback() is executed and user can
  63. add his own code by customization of function pointer HAL_SMBUS_SlaveRxCpltCallback()
  64. (+) Enable/Disable the SMBUS alert mode using HAL_SMBUS_EnableAlert_IT() HAL_SMBUS_DisableAlert_IT()
  65. (++) When SMBUS Alert is generated HAL_SMBUS_ErrorCallback() is executed and user can
  66. add his own code by customization of function pointer HAL_SMBUS_ErrorCallback()
  67. to check the Alert Error Code using function HAL_SMBUS_GetError()
  68. (+) Get HAL state machine or error values using HAL_SMBUS_GetState() or HAL_SMBUS_GetError()
  69. (+) In case of transfer Error, HAL_SMBUS_ErrorCallback() function is executed and user can
  70. add his own code by customization of function pointer HAL_SMBUS_ErrorCallback()
  71. to check the Error Code using function HAL_SMBUS_GetError()
  72. *** SMBUS HAL driver macros list ***
  73. ==================================
  74. [..]
  75. Below the list of most used macros in SMBUS HAL driver.
  76. (+) __HAL_SMBUS_ENABLE: Enable the SMBUS peripheral
  77. (+) __HAL_SMBUS_DISABLE: Disable the SMBUS peripheral
  78. (+) __HAL_SMBUS_GET_FLAG : Checks whether the specified SMBUS flag is set or not
  79. (+) __HAL_SMBUS_CLEAR_FLAG : Clears the specified SMBUS pending flag
  80. (+) __HAL_SMBUS_ENABLE_IT: Enables the specified SMBUS interrupt
  81. (+) __HAL_SMBUS_DISABLE_IT: Disables the specified SMBUS interrupt
  82. [..]
  83. (@) You can refer to the SMBUS HAL driver header file for more useful macros
  84. @endverbatim
  85. ******************************************************************************
  86. * @attention
  87. *
  88. * <h2><center>&copy; COPYRIGHT(c) 2017 STMicroelectronics</center></h2>
  89. *
  90. * Redistribution and use in source and binary forms, with or without modification,
  91. * are permitted provided that the following conditions are met:
  92. * 1. Redistributions of source code must retain the above copyright notice,
  93. * this list of conditions and the following disclaimer.
  94. * 2. Redistributions in binary form must reproduce the above copyright notice,
  95. * this list of conditions and the following disclaimer in the documentation
  96. * and/or other materials provided with the distribution.
  97. * 3. Neither the name of STMicroelectronics nor the names of its contributors
  98. * may be used to endorse or promote products derived from this software
  99. * without specific prior written permission.
  100. *
  101. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  102. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  103. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  104. * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
  105. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  106. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  107. * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  108. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  109. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  110. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  111. *
  112. ******************************************************************************
  113. */
  114. /* Includes ------------------------------------------------------------------*/
  115. #include "stm32h7xx_hal.h"
  116. /** @addtogroup STM32H7xx_HAL_Driver
  117. * @{
  118. */
  119. /** @defgroup SMBUS SMBUS
  120. * @brief SMBUS HAL module driver
  121. * @{
  122. */
  123. #ifdef HAL_SMBUS_MODULE_ENABLED
  124. /* Private typedef -----------------------------------------------------------*/
  125. /* Private constants ---------------------------------------------------------*/
  126. /** @defgroup SMBUS_Private_Define SMBUS Private Constants
  127. * @{
  128. */
  129. #define TIMING_CLEAR_MASK ((uint32_t)0xF0FFFFFF) /*<! SMBUS TIMING clear register Mask */
  130. #define HAL_TIMEOUT_ADDR ((uint32_t)10000) /* 10 s */
  131. #define HAL_TIMEOUT_BUSY ((uint32_t)25) /* 25 ms */
  132. #define HAL_TIMEOUT_DIR ((uint32_t)25) /* 25 ms */
  133. #define HAL_TIMEOUT_RXNE ((uint32_t)25) /* 25 ms */
  134. #define HAL_TIMEOUT_STOPF ((uint32_t)25) /* 25 ms */
  135. #define HAL_TIMEOUT_TC ((uint32_t)25) /* 25 ms */
  136. #define HAL_TIMEOUT_TCR ((uint32_t)25) /* 25 ms */
  137. #define HAL_TIMEOUT_TXIS ((uint32_t)25) /* 25 ms */
  138. #define MAX_NBYTE_SIZE 255
  139. /**
  140. * @}
  141. */
  142. /* Private macro -------------------------------------------------------------*/
  143. /* Private variables ---------------------------------------------------------*/
  144. /* Private function prototypes -----------------------------------------------*/
  145. /** @addtogroup SMBUS_Private_Functions SMBUS Private Functions
  146. * @{
  147. */
  148. static HAL_StatusTypeDef SMBUS_WaitOnFlagUntilTimeout(SMBUS_HandleTypeDef *hsmbus, uint32_t Flag, FlagStatus Status, uint32_t Timeout);
  149. static HAL_StatusTypeDef SMBUS_Enable_IRQ(SMBUS_HandleTypeDef *hsmbus, uint16_t InterruptRequest);
  150. static HAL_StatusTypeDef SMBUS_Disable_IRQ(SMBUS_HandleTypeDef *hsmbus, uint16_t InterruptRequest);
  151. static HAL_StatusTypeDef SMBUS_Master_ISR(SMBUS_HandleTypeDef *hsmbus);
  152. static HAL_StatusTypeDef SMBUS_Slave_ISR(SMBUS_HandleTypeDef *hsmbus);
  153. static void SMBUS_ConvertOtherXferOptions(SMBUS_HandleTypeDef *hsmbus);
  154. static void SMBUS_TransferConfig(SMBUS_HandleTypeDef *hsmbus, uint16_t DevAddress, uint8_t Size, uint32_t Mode, uint32_t Request);
  155. /**
  156. * @}
  157. */
  158. /* Exported functions --------------------------------------------------------*/
  159. /** @defgroup SMBUS_Exported_Functions SMBUS Exported Functions
  160. * @{
  161. */
  162. /** @defgroup SMBUS_Exported_Functions_Group1 Initialization and de-initialization functions
  163. * @brief Initialization and Configuration functions
  164. *
  165. @verbatim
  166. ===============================================================================
  167. ##### Initialization and de-initialization functions #####
  168. ===============================================================================
  169. [..] This subsection provides a set of functions allowing to initialize and
  170. de-initialize the SMBUSx peripheral:
  171. (+) User must Implement HAL_SMBUS_MspInit() function in which he configures
  172. all related peripherals resources (CLOCK, GPIO, IT and NVIC ).
  173. (+) Call the function HAL_SMBUS_Init() to configure the selected device with
  174. the selected configuration:
  175. (++) Clock Timing
  176. (++) Bus Timeout
  177. (++) Analog Filer mode
  178. (++) Own Address 1
  179. (++) Addressing mode (Master, Slave)
  180. (++) Dual Addressing mode
  181. (++) Own Address 2
  182. (++) Own Address 2 Mask
  183. (++) General call mode
  184. (++) Nostretch mode
  185. (++) Packet Error Check mode
  186. (++) Peripheral mode
  187. (+) Call the function HAL_SMBUS_DeInit() to restore the default configuration
  188. of the selected SMBUSx peripheral.
  189. @endverbatim
  190. * @{
  191. */
  192. /**
  193. * @brief Initialize the SMBUS according to the specified parameters
  194. * in the SMBUS_InitTypeDef and initialize the associated handle.
  195. * @param hsmbus : Pointer to a SMBUS_HandleTypeDef structure that contains
  196. * the configuration information for the specified SMBUS.
  197. * @retval HAL status
  198. */
  199. HAL_StatusTypeDef HAL_SMBUS_Init(SMBUS_HandleTypeDef *hsmbus)
  200. {
  201. /* Check the SMBUS handle allocation */
  202. if(hsmbus == NULL)
  203. {
  204. return HAL_ERROR;
  205. }
  206. /* Check the parameters */
  207. assert_param(IS_SMBUS_ALL_INSTANCE(hsmbus->Instance));
  208. assert_param(IS_SMBUS_ANALOG_FILTER(hsmbus->Init.AnalogFilter));
  209. assert_param(IS_SMBUS_OWN_ADDRESS1(hsmbus->Init.OwnAddress1));
  210. assert_param(IS_SMBUS_ADDRESSING_MODE(hsmbus->Init.AddressingMode));
  211. assert_param(IS_SMBUS_DUAL_ADDRESS(hsmbus->Init.DualAddressMode));
  212. assert_param(IS_SMBUS_OWN_ADDRESS2(hsmbus->Init.OwnAddress2));
  213. assert_param(IS_SMBUS_OWN_ADDRESS2_MASK(hsmbus->Init.OwnAddress2Masks));
  214. assert_param(IS_SMBUS_GENERAL_CALL(hsmbus->Init.GeneralCallMode));
  215. assert_param(IS_SMBUS_NO_STRETCH(hsmbus->Init.NoStretchMode));
  216. assert_param(IS_SMBUS_PEC(hsmbus->Init.PacketErrorCheckMode));
  217. assert_param(IS_SMBUS_PERIPHERAL_MODE(hsmbus->Init.PeripheralMode));
  218. if(hsmbus->State == HAL_SMBUS_STATE_RESET)
  219. {
  220. /* Allocate lock resource and initialize it */
  221. hsmbus->Lock = HAL_UNLOCKED;
  222. /* Init the low level hardware : GPIO, CLOCK, NVIC */
  223. HAL_SMBUS_MspInit(hsmbus);
  224. }
  225. hsmbus->State = HAL_SMBUS_STATE_BUSY;
  226. /* Disable the selected SMBUS peripheral */
  227. __HAL_SMBUS_DISABLE(hsmbus);
  228. /*---------------------------- SMBUSx TIMINGR Configuration ------------------------*/
  229. /* Configure SMBUSx: Frequency range */
  230. hsmbus->Instance->TIMINGR = hsmbus->Init.Timing & TIMING_CLEAR_MASK;
  231. /*---------------------------- SMBUSx TIMEOUTR Configuration ------------------------*/
  232. /* Configure SMBUSx: Bus Timeout */
  233. hsmbus->Instance->TIMEOUTR &= ~I2C_TIMEOUTR_TIMOUTEN;
  234. hsmbus->Instance->TIMEOUTR &= ~I2C_TIMEOUTR_TEXTEN;
  235. hsmbus->Instance->TIMEOUTR = hsmbus->Init.SMBusTimeout;
  236. /*---------------------------- SMBUSx OAR1 Configuration -----------------------*/
  237. /* Configure SMBUSx: Own Address1 and ack own address1 mode */
  238. hsmbus->Instance->OAR1 &= ~I2C_OAR1_OA1EN;
  239. if(hsmbus->Init.OwnAddress1 != 0U)
  240. {
  241. if(hsmbus->Init.AddressingMode == SMBUS_ADDRESSINGMODE_7BIT)
  242. {
  243. hsmbus->Instance->OAR1 = (I2C_OAR1_OA1EN | hsmbus->Init.OwnAddress1);
  244. }
  245. else /* SMBUS_ADDRESSINGMODE_10BIT */
  246. {
  247. hsmbus->Instance->OAR1 = (I2C_OAR1_OA1EN | I2C_OAR1_OA1MODE | hsmbus->Init.OwnAddress1);
  248. }
  249. }
  250. /*---------------------------- SMBUSx CR2 Configuration ------------------------*/
  251. /* Configure SMBUSx: Addressing Master mode */
  252. if(hsmbus->Init.AddressingMode == SMBUS_ADDRESSINGMODE_10BIT)
  253. {
  254. hsmbus->Instance->CR2 = (I2C_CR2_ADD10);
  255. }
  256. /* Enable the AUTOEND by default, and enable NACK (should be disable only during Slave process) */
  257. /* AUTOEND and NACK bit will be manage during Transfer process */
  258. hsmbus->Instance->CR2 |= (I2C_CR2_AUTOEND | I2C_CR2_NACK);
  259. /*---------------------------- SMBUSx OAR2 Configuration -----------------------*/
  260. /* Configure SMBUSx: Dual mode and Own Address2 */
  261. hsmbus->Instance->OAR2 = (hsmbus->Init.DualAddressMode | hsmbus->Init.OwnAddress2 | (hsmbus->Init.OwnAddress2Masks << 8U));
  262. /*---------------------------- SMBUSx CR1 Configuration ------------------------*/
  263. /* Configure SMBUSx: Generalcall and NoStretch mode */
  264. hsmbus->Instance->CR1 = (hsmbus->Init.GeneralCallMode | hsmbus->Init.NoStretchMode | hsmbus->Init.PacketErrorCheckMode | hsmbus->Init.PeripheralMode | hsmbus->Init.AnalogFilter);
  265. /* Enable Slave Byte Control only in case of Packet Error Check is enabled and SMBUS Peripheral is set in Slave mode */
  266. if( (hsmbus->Init.PacketErrorCheckMode == SMBUS_PEC_ENABLE)
  267. && ( (hsmbus->Init.PeripheralMode == SMBUS_PERIPHERAL_MODE_SMBUS_SLAVE) || (hsmbus->Init.PeripheralMode == SMBUS_PERIPHERAL_MODE_SMBUS_SLAVE_ARP) ) )
  268. {
  269. hsmbus->Instance->CR1 |= I2C_CR1_SBC;
  270. }
  271. /* Enable the selected SMBUS peripheral */
  272. __HAL_SMBUS_ENABLE(hsmbus);
  273. hsmbus->ErrorCode = HAL_SMBUS_ERROR_NONE;
  274. hsmbus->PreviousState = HAL_SMBUS_STATE_READY;
  275. hsmbus->State = HAL_SMBUS_STATE_READY;
  276. return HAL_OK;
  277. }
  278. /**
  279. * @brief DeInitialize the SMBUS peripheral.
  280. * @param hsmbus : Pointer to a SMBUS_HandleTypeDef structure that contains
  281. * the configuration information for the specified SMBUS.
  282. * @retval HAL status
  283. */
  284. HAL_StatusTypeDef HAL_SMBUS_DeInit(SMBUS_HandleTypeDef *hsmbus)
  285. {
  286. /* Check the SMBUS handle allocation */
  287. if(hsmbus == NULL)
  288. {
  289. return HAL_ERROR;
  290. }
  291. /* Check the parameters */
  292. assert_param(IS_SMBUS_ALL_INSTANCE(hsmbus->Instance));
  293. hsmbus->State = HAL_SMBUS_STATE_BUSY;
  294. /* Disable the SMBUS Peripheral Clock */
  295. __HAL_SMBUS_DISABLE(hsmbus);
  296. /* DeInit the low level hardware: GPIO, CLOCK, NVIC */
  297. HAL_SMBUS_MspDeInit(hsmbus);
  298. hsmbus->ErrorCode = HAL_SMBUS_ERROR_NONE;
  299. hsmbus->PreviousState = HAL_SMBUS_STATE_RESET;
  300. hsmbus->State = HAL_SMBUS_STATE_RESET;
  301. /* Release Lock */
  302. __HAL_UNLOCK(hsmbus);
  303. return HAL_OK;
  304. }
  305. /**
  306. * @brief Initialize the SMBUS MSP.
  307. * @param hsmbus : Pointer to a SMBUS_HandleTypeDef structure that contains
  308. * the configuration information for the specified SMBUS.
  309. * @retval None
  310. */
  311. __weak void HAL_SMBUS_MspInit(SMBUS_HandleTypeDef *hsmbus)
  312. {
  313. /* Prevent unused argument(s) compilation warning */
  314. UNUSED(hsmbus);
  315. /* NOTE : This function should not be modified, when the callback is needed,
  316. the HAL_SMBUS_MspInit could be implemented in the user file
  317. */
  318. }
  319. /**
  320. * @brief DeInitialize the SMBUS MSP.
  321. * @param hsmbus : Pointer to a SMBUS_HandleTypeDef structure that contains
  322. * the configuration information for the specified SMBUS.
  323. * @retval None
  324. */
  325. __weak void HAL_SMBUS_MspDeInit(SMBUS_HandleTypeDef *hsmbus)
  326. {
  327. /* Prevent unused argument(s) compilation warning */
  328. UNUSED(hsmbus);
  329. /* NOTE : This function should not be modified, when the callback is needed,
  330. the HAL_SMBUS_MspDeInit could be implemented in the user file
  331. */
  332. }
  333. /**
  334. * @}
  335. */
  336. /** @defgroup SMBUS_Exported_Functions_Group2 Input and Output operation functions
  337. * @brief Data transfers functions
  338. *
  339. @verbatim
  340. ===============================================================================
  341. ##### IO operation functions #####
  342. ===============================================================================
  343. [..]
  344. This subsection provides a set of functions allowing to manage the SMBUS data
  345. transfers.
  346. (#) Blocking mode function to check if device is ready for usage is :
  347. (++) HAL_SMBUS_IsDeviceReady()
  348. (#) There is only one mode of transfer:
  349. (++) Non-Blocking mode : The communication is performed using Interrupts.
  350. These functions return the status of the transfer startup.
  351. The end of the data processing will be indicated through the
  352. dedicated SMBUS IRQ when using Interrupt mode.
  353. (#) Non-Blocking mode functions with Interrupt are :
  354. (++) HAL_SMBUS_Master_Transmit_IT()
  355. (++) HAL_SMBUS_Master_Receive_IT()
  356. (++) HAL_SMBUS_Slave_Transmit_IT()
  357. (++) HAL_SMBUS_Slave_Receive_IT()
  358. (++) HAL_SMBUS_EnableListen_IT()
  359. (++) HAL_SMBUS_DisableListen_IT()
  360. (++) HAL_SMBUS_EnableAlert_IT()
  361. (++) HAL_SMBUS_DisableAlert_IT()
  362. (#) A set of Transfer Complete Callbacks are provided in Non_Blocking mode:
  363. (++) HAL_SMBUS_MasterTxCpltCallback()
  364. (++) HAL_SMBUS_MasterRxCpltCallback()
  365. (++) HAL_SMBUS_SlaveTxCpltCallback()
  366. (++) HAL_SMBUS_SlaveRxCpltCallback()
  367. (++) HAL_SMBUS_AddrCallback()
  368. (++) HAL_SMBUS_ListenCpltCallback()
  369. (++) HAL_SMBUS_ErrorCallback()
  370. @endverbatim
  371. * @{
  372. */
  373. /**
  374. * @brief Transmit in master/host SMBUS mode an amount of data in non-blocking mode with Interrupt.
  375. * @param hsmbus : Pointer to a SMBUS_HandleTypeDef structure that contains
  376. * the configuration information for the specified SMBUS.
  377. * @param DevAddress: Target device address
  378. * @param pData: Pointer to data buffer
  379. * @param Size: Amount of data to be sent
  380. * @param XferOptions: Options of Transfer, value of @ref SMBUS_XferOptions_definition
  381. * @retval HAL status
  382. */
  383. HAL_StatusTypeDef HAL_SMBUS_Master_Transmit_IT(SMBUS_HandleTypeDef *hsmbus, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t XferOptions)
  384. {
  385. /* Check the parameters */
  386. assert_param(IS_SMBUS_TRANSFER_OPTIONS_REQUEST(XferOptions));
  387. if(hsmbus->State == HAL_SMBUS_STATE_READY)
  388. {
  389. /* Process Locked */
  390. __HAL_LOCK(hsmbus);
  391. hsmbus->State = HAL_SMBUS_STATE_MASTER_BUSY_TX;
  392. hsmbus->ErrorCode = HAL_SMBUS_ERROR_NONE;
  393. /* Prepare transfer parameters */
  394. hsmbus->pBuffPtr = pData;
  395. hsmbus->XferCount = Size;
  396. hsmbus->XferOptions = XferOptions;
  397. /* In case of Quick command, remove autoend mode */
  398. /* Manage the stop generation by software */
  399. if(hsmbus->pBuffPtr == NULL)
  400. {
  401. hsmbus->XferOptions &= ~SMBUS_AUTOEND_MODE;
  402. }
  403. if(Size > MAX_NBYTE_SIZE)
  404. {
  405. hsmbus->XferSize = MAX_NBYTE_SIZE;
  406. }
  407. else
  408. {
  409. hsmbus->XferSize = Size;
  410. }
  411. /* Send Slave Address */
  412. /* Set NBYTES to write and reload if size > MAX_NBYTE_SIZE and generate RESTART */
  413. if( (hsmbus->XferSize == MAX_NBYTE_SIZE) && (hsmbus->XferSize < hsmbus->XferCount) )
  414. {
  415. SMBUS_TransferConfig(hsmbus,DevAddress,hsmbus->XferSize, SMBUS_RELOAD_MODE | (hsmbus->XferOptions & SMBUS_SENDPEC_MODE), SMBUS_GENERATE_START_WRITE);
  416. }
  417. else
  418. {
  419. /* If transfer direction not change, do not generate Restart Condition */
  420. /* Mean Previous state is same as current state */
  421. if((hsmbus->PreviousState == HAL_SMBUS_STATE_MASTER_BUSY_TX) && (IS_SMBUS_TRANSFER_OTHER_OPTIONS_REQUEST(hsmbus->XferOptions) == 0))
  422. {
  423. SMBUS_TransferConfig(hsmbus,DevAddress,hsmbus->XferSize, hsmbus->XferOptions, SMBUS_NO_STARTSTOP);
  424. }
  425. /* Else transfer direction change, so generate Restart with new transfer direction */
  426. else
  427. {
  428. /* Convert OTHER_xxx XferOptions if any */
  429. SMBUS_ConvertOtherXferOptions(hsmbus);
  430. /* Handle Transfer */
  431. SMBUS_TransferConfig(hsmbus,DevAddress,hsmbus->XferSize, hsmbus->XferOptions, SMBUS_GENERATE_START_WRITE);
  432. }
  433. /* If PEC mode is enable, size to transmit manage by SW part should be Size-1 byte, corresponding to PEC byte */
  434. /* PEC byte is automatically sent by HW block, no need to manage it in Transmit process */
  435. if(SMBUS_GET_PEC_MODE(hsmbus) != RESET)
  436. {
  437. hsmbus->XferSize--;
  438. hsmbus->XferCount--;
  439. }
  440. }
  441. /* Process Unlocked */
  442. __HAL_UNLOCK(hsmbus);
  443. /* Note : The SMBUS interrupts must be enabled after unlocking current process
  444. to avoid the risk of SMBUS interrupt handle execution before current
  445. process unlock */
  446. SMBUS_Enable_IRQ(hsmbus, SMBUS_IT_TX);
  447. return HAL_OK;
  448. }
  449. else
  450. {
  451. return HAL_BUSY;
  452. }
  453. }
  454. /**
  455. * @brief Receive in master/host SMBUS mode an amount of data in non-blocking mode with Interrupt.
  456. * @param hsmbus : Pointer to a SMBUS_HandleTypeDef structure that contains
  457. * the configuration information for the specified SMBUS.
  458. * @param DevAddress: Target device address
  459. * @param pData: Pointer to data buffer
  460. * @param Size: Amount of data to be sent
  461. * @param XferOptions: Options of Transfer, value of @ref SMBUS_XferOptions_definition
  462. * @retval HAL status
  463. */
  464. HAL_StatusTypeDef HAL_SMBUS_Master_Receive_IT(SMBUS_HandleTypeDef *hsmbus, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t XferOptions)
  465. {
  466. /* Check the parameters */
  467. assert_param(IS_SMBUS_TRANSFER_OPTIONS_REQUEST(XferOptions));
  468. if(hsmbus->State == HAL_SMBUS_STATE_READY)
  469. {
  470. /* Process Locked */
  471. __HAL_LOCK(hsmbus);
  472. hsmbus->State = HAL_SMBUS_STATE_MASTER_BUSY_RX;
  473. hsmbus->ErrorCode = HAL_SMBUS_ERROR_NONE;
  474. /* Prepare transfer parameters */
  475. hsmbus->pBuffPtr = pData;
  476. hsmbus->XferCount = Size;
  477. hsmbus->XferOptions = XferOptions;
  478. /* In case of Quick command, remove autoend mode */
  479. /* Manage the stop generation by software */
  480. if(hsmbus->pBuffPtr == NULL)
  481. {
  482. hsmbus->XferOptions &= ~SMBUS_AUTOEND_MODE;
  483. }
  484. if(Size > MAX_NBYTE_SIZE)
  485. {
  486. hsmbus->XferSize = MAX_NBYTE_SIZE;
  487. }
  488. else
  489. {
  490. hsmbus->XferSize = Size;
  491. }
  492. /* Send Slave Address */
  493. /* Set NBYTES to write and reload if size > MAX_NBYTE_SIZE and generate RESTART */
  494. if( (hsmbus->XferSize == MAX_NBYTE_SIZE) && (hsmbus->XferSize < hsmbus->XferCount) )
  495. {
  496. SMBUS_TransferConfig(hsmbus,DevAddress,hsmbus->XferSize, SMBUS_RELOAD_MODE | (hsmbus->XferOptions & SMBUS_SENDPEC_MODE), SMBUS_GENERATE_START_READ);
  497. }
  498. else
  499. {
  500. /* If transfer direction not change, do not generate Restart Condition */
  501. /* Mean Previous state is same as current state */
  502. if((hsmbus->PreviousState == HAL_SMBUS_STATE_MASTER_BUSY_RX) && (IS_SMBUS_TRANSFER_OTHER_OPTIONS_REQUEST(hsmbus->XferOptions) == 0))
  503. {
  504. SMBUS_TransferConfig(hsmbus,DevAddress,hsmbus->XferSize, hsmbus->XferOptions, SMBUS_NO_STARTSTOP);
  505. }
  506. /* Else transfer direction change, so generate Restart with new transfer direction */
  507. else
  508. {
  509. /* Convert OTHER_xxx XferOptions if any */
  510. SMBUS_ConvertOtherXferOptions(hsmbus);
  511. /* Handle Transfer */
  512. SMBUS_TransferConfig(hsmbus,DevAddress,hsmbus->XferSize, hsmbus->XferOptions, SMBUS_GENERATE_START_READ);
  513. }
  514. }
  515. /* Process Unlocked */
  516. __HAL_UNLOCK(hsmbus);
  517. /* Note : The SMBUS interrupts must be enabled after unlocking current process
  518. to avoid the risk of SMBUS interrupt handle execution before current
  519. process unlock */
  520. SMBUS_Enable_IRQ(hsmbus, SMBUS_IT_RX);
  521. return HAL_OK;
  522. }
  523. else
  524. {
  525. return HAL_BUSY;
  526. }
  527. }
  528. /**
  529. * @brief Abort a master/host SMBUS process communication with Interrupt.
  530. * @note This abort can be called only if state is ready
  531. * @param hsmbus : Pointer to a SMBUS_HandleTypeDef structure that contains
  532. * the configuration information for the specified SMBUS.
  533. * @param DevAddress: Target device address
  534. * @retval HAL status
  535. */
  536. HAL_StatusTypeDef HAL_SMBUS_Master_Abort_IT(SMBUS_HandleTypeDef *hsmbus, uint16_t DevAddress)
  537. {
  538. if(hsmbus->State == HAL_SMBUS_STATE_READY)
  539. {
  540. /* Process Locked */
  541. __HAL_LOCK(hsmbus);
  542. /* Keep the same state as previous */
  543. /* to perform as well the call of the corresponding end of transfer callback */
  544. if(hsmbus->PreviousState == HAL_SMBUS_STATE_MASTER_BUSY_TX)
  545. {
  546. hsmbus->State = HAL_SMBUS_STATE_MASTER_BUSY_TX;
  547. }
  548. else if(hsmbus->PreviousState == HAL_SMBUS_STATE_MASTER_BUSY_RX)
  549. {
  550. hsmbus->State = HAL_SMBUS_STATE_MASTER_BUSY_RX;
  551. }
  552. else
  553. {
  554. /* Wrong usage of abort function */
  555. /* This function should be used only in case of abort monitored by master device */
  556. return HAL_ERROR;
  557. }
  558. hsmbus->ErrorCode = HAL_SMBUS_ERROR_NONE;
  559. /* Set NBYTES to 1 to generate a dummy read on SMBUS peripheral */
  560. /* Set AUTOEND mode, this will generate a NACK then STOP condition to abort the current transfer */
  561. SMBUS_TransferConfig(hsmbus, DevAddress, 1U, SMBUS_AUTOEND_MODE, SMBUS_NO_STARTSTOP);
  562. /* Process Unlocked */
  563. __HAL_UNLOCK(hsmbus);
  564. /* Note : The SMBUS interrupts must be enabled after unlocking current process
  565. to avoid the risk of SMBUS interrupt handle execution before current
  566. process unlock */
  567. if(hsmbus->State == HAL_SMBUS_STATE_MASTER_BUSY_TX)
  568. {
  569. SMBUS_Enable_IRQ(hsmbus, SMBUS_IT_TX);
  570. }
  571. else if(hsmbus->State == HAL_SMBUS_STATE_MASTER_BUSY_RX)
  572. {
  573. SMBUS_Enable_IRQ(hsmbus, SMBUS_IT_RX);
  574. }
  575. return HAL_OK;
  576. }
  577. else
  578. {
  579. return HAL_BUSY;
  580. }
  581. }
  582. /**
  583. * @brief Transmit in slave/device SMBUS mode an amount of data in non-blocking mode with Interrupt.
  584. * @param hsmbus : Pointer to a SMBUS_HandleTypeDef structure that contains
  585. * the configuration information for the specified SMBUS.
  586. * @param pData: Pointer to data buffer
  587. * @param Size: Amount of data to be sent
  588. * @param XferOptions: Options of Transfer, value of @ref SMBUS_XferOptions_definition
  589. * @retval HAL status
  590. */
  591. HAL_StatusTypeDef HAL_SMBUS_Slave_Transmit_IT(SMBUS_HandleTypeDef *hsmbus, uint8_t *pData, uint16_t Size, uint32_t XferOptions)
  592. {
  593. /* Check the parameters */
  594. assert_param(IS_SMBUS_TRANSFER_OPTIONS_REQUEST(XferOptions));
  595. if(hsmbus->State == HAL_SMBUS_STATE_LISTEN)
  596. {
  597. if((pData == NULL) || (Size == 0U))
  598. {
  599. return HAL_ERROR;
  600. }
  601. /* Disable Interrupts, to prevent preemption during treatment in case of multicall */
  602. SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_ADDR | SMBUS_IT_TX);
  603. /* Process Locked */
  604. __HAL_LOCK(hsmbus);
  605. hsmbus->State |= HAL_SMBUS_STATE_SLAVE_BUSY_TX;
  606. hsmbus->ErrorCode = HAL_SMBUS_ERROR_NONE;
  607. /* Set SBC bit to manage Acknowledge at each bit */
  608. hsmbus->Instance->CR1 |= I2C_CR1_SBC;
  609. /* Enable Address Acknowledge */
  610. hsmbus->Instance->CR2 &= ~I2C_CR2_NACK;
  611. /* Prepare transfer parameters */
  612. hsmbus->pBuffPtr = pData;
  613. hsmbus->XferCount = Size;
  614. hsmbus->XferOptions = XferOptions;
  615. /* Convert OTHER_xxx XferOptions if any */
  616. SMBUS_ConvertOtherXferOptions(hsmbus);
  617. if(Size > MAX_NBYTE_SIZE)
  618. {
  619. hsmbus->XferSize = MAX_NBYTE_SIZE;
  620. }
  621. else
  622. {
  623. hsmbus->XferSize = Size;
  624. }
  625. /* Set NBYTES to write and reload if size > MAX_NBYTE_SIZE and generate RESTART */
  626. if( (hsmbus->XferSize == MAX_NBYTE_SIZE) && (hsmbus->XferSize < hsmbus->XferCount) )
  627. {
  628. SMBUS_TransferConfig(hsmbus, 0U,hsmbus->XferSize, SMBUS_RELOAD_MODE | (hsmbus->XferOptions & SMBUS_SENDPEC_MODE), SMBUS_NO_STARTSTOP);
  629. }
  630. else
  631. {
  632. /* Set NBYTE to transmit */
  633. SMBUS_TransferConfig(hsmbus, 0U,hsmbus->XferSize, hsmbus->XferOptions, SMBUS_NO_STARTSTOP);
  634. /* If PEC mode is enable, size to transmit should be Size-1 byte, corresponding to PEC byte */
  635. /* PEC byte is automatically sent by HW block, no need to manage it in Transmit process */
  636. if(SMBUS_GET_PEC_MODE(hsmbus) != RESET)
  637. {
  638. hsmbus->XferSize--;
  639. hsmbus->XferCount--;
  640. }
  641. }
  642. /* Clear ADDR flag after prepare the transfer parameters */
  643. /* This action will generate an acknowledge to the HOST */
  644. __HAL_SMBUS_CLEAR_FLAG(hsmbus,SMBUS_FLAG_ADDR);
  645. /* Process Unlocked */
  646. __HAL_UNLOCK(hsmbus);
  647. /* Note : The SMBUS interrupts must be enabled after unlocking current process
  648. to avoid the risk of SMBUS interrupt handle execution before current
  649. process unlock */
  650. /* REnable ADDR interrupt */
  651. SMBUS_Enable_IRQ(hsmbus, SMBUS_IT_TX | SMBUS_IT_ADDR);
  652. return HAL_OK;
  653. }
  654. else
  655. {
  656. return HAL_ERROR;
  657. }
  658. }
  659. /**
  660. * @brief Receive in slave/device SMBUS mode an amount of data in non-blocking mode with Interrupt.
  661. * @param hsmbus : Pointer to a SMBUS_HandleTypeDef structure that contains
  662. * the configuration information for the specified SMBUS.
  663. * @param pData: Pointer to data buffer
  664. * @param Size: Amount of data to be sent
  665. * @param XferOptions: Options of Transfer, value of @ref SMBUS_XferOptions_definition
  666. * @retval HAL status
  667. */
  668. HAL_StatusTypeDef HAL_SMBUS_Slave_Receive_IT(SMBUS_HandleTypeDef *hsmbus, uint8_t *pData, uint16_t Size, uint32_t XferOptions)
  669. {
  670. /* Check the parameters */
  671. assert_param(IS_SMBUS_TRANSFER_OPTIONS_REQUEST(XferOptions));
  672. if(hsmbus->State == HAL_SMBUS_STATE_LISTEN)
  673. {
  674. if((pData == NULL) || (Size == 0U))
  675. {
  676. return HAL_ERROR;
  677. }
  678. /* Disable Interrupts, to prevent preemption during treatment in case of multicall */
  679. SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_ADDR | SMBUS_IT_RX);
  680. /* Process Locked */
  681. __HAL_LOCK(hsmbus);
  682. hsmbus->State |= HAL_SMBUS_STATE_SLAVE_BUSY_RX;
  683. hsmbus->ErrorCode = HAL_SMBUS_ERROR_NONE;
  684. /* Set SBC bit to manage Acknowledge at each bit */
  685. hsmbus->Instance->CR1 |= I2C_CR1_SBC;
  686. /* Enable Address Acknowledge */
  687. hsmbus->Instance->CR2 &= ~I2C_CR2_NACK;
  688. /* Prepare transfer parameters */
  689. hsmbus->pBuffPtr = pData;
  690. hsmbus->XferSize = Size;
  691. hsmbus->XferCount = Size;
  692. hsmbus->XferOptions = XferOptions;
  693. /* Convert OTHER_xxx XferOptions if any */
  694. SMBUS_ConvertOtherXferOptions(hsmbus);
  695. /* Set NBYTE to receive */
  696. /* If XferSize equal "1", or XferSize equal "2" with PEC requested (mean 1 data byte + 1 PEC byte */
  697. /* no need to set RELOAD bit mode, a ACK will be automatically generated in that case */
  698. /* else need to set RELOAD bit mode to generate an automatic ACK at each byte Received */
  699. /* This RELOAD bit will be reset for last BYTE to be receive in SMBUS_Slave_ISR */
  700. if((hsmbus->XferSize == 1U) || ((hsmbus->XferSize == 2U) && (SMBUS_GET_PEC_MODE(hsmbus) != RESET)))
  701. {
  702. SMBUS_TransferConfig(hsmbus, 0U, hsmbus->XferSize, hsmbus->XferOptions, SMBUS_NO_STARTSTOP);
  703. }
  704. else
  705. {
  706. SMBUS_TransferConfig(hsmbus, 0U, 1U, hsmbus->XferOptions | SMBUS_RELOAD_MODE, SMBUS_NO_STARTSTOP);
  707. }
  708. /* Clear ADDR flag after prepare the transfer parameters */
  709. /* This action will generate an acknowledge to the HOST */
  710. __HAL_SMBUS_CLEAR_FLAG(hsmbus,SMBUS_FLAG_ADDR);
  711. /* Process Unlocked */
  712. __HAL_UNLOCK(hsmbus);
  713. /* Note : The SMBUS interrupts must be enabled after unlocking current process
  714. to avoid the risk of SMBUS interrupt handle execution before current
  715. process unlock */
  716. /* REnable ADDR interrupt */
  717. SMBUS_Enable_IRQ(hsmbus, SMBUS_IT_RX | SMBUS_IT_ADDR);
  718. return HAL_OK;
  719. }
  720. else
  721. {
  722. return HAL_ERROR;
  723. }
  724. }
  725. /**
  726. * @brief Enable the Address listen mode with Interrupt.
  727. * @param hsmbus : Pointer to a SMBUS_HandleTypeDef structure that contains
  728. * the configuration information for the specified SMBUS.
  729. * @retval HAL status
  730. */
  731. HAL_StatusTypeDef HAL_SMBUS_EnableListen_IT(SMBUS_HandleTypeDef *hsmbus)
  732. {
  733. hsmbus->State = HAL_SMBUS_STATE_LISTEN;
  734. /* Enable the Address Match interrupt */
  735. SMBUS_Enable_IRQ(hsmbus, SMBUS_IT_ADDR);
  736. return HAL_OK;
  737. }
  738. /**
  739. * @brief Disable the Address listen mode with Interrupt.
  740. * @param hsmbus : Pointer to a SMBUS_HandleTypeDef structure that contains
  741. * the configuration information for the specified SMBUS.
  742. * @retval HAL status
  743. */
  744. HAL_StatusTypeDef HAL_SMBUS_DisableListen_IT(SMBUS_HandleTypeDef *hsmbus)
  745. {
  746. /* Disable Address listen mode only if a transfer is not ongoing */
  747. if(hsmbus->State == HAL_SMBUS_STATE_LISTEN)
  748. {
  749. hsmbus->State = HAL_SMBUS_STATE_READY;
  750. /* Disable the Address Match interrupt */
  751. SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_ADDR);
  752. return HAL_OK;
  753. }
  754. else
  755. {
  756. return HAL_BUSY;
  757. }
  758. }
  759. /**
  760. * @brief Enable the SMBUS alert mode with Interrupt.
  761. * @param hsmbus : pointer to a SMBUS_HandleTypeDef structure that contains
  762. * the configuration information for the specified SMBUSx peripheral.
  763. * @retval HAL status
  764. */
  765. HAL_StatusTypeDef HAL_SMBUS_EnableAlert_IT(SMBUS_HandleTypeDef *hsmbus)
  766. {
  767. /* Enable SMBus alert */
  768. hsmbus->Instance->CR1 |= I2C_CR1_ALERTEN;
  769. /* Clear ALERT flag */
  770. __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_ALERT);
  771. /* Enable Alert Interrupt */
  772. SMBUS_Enable_IRQ(hsmbus, SMBUS_IT_ALERT);
  773. return HAL_OK;
  774. }
  775. /**
  776. * @brief Disable the SMBUS alert mode with Interrupt.
  777. * @param hsmbus : pointer to a SMBUS_HandleTypeDef structure that contains
  778. * the configuration information for the specified SMBUSx peripheral.
  779. * @retval HAL status
  780. */
  781. HAL_StatusTypeDef HAL_SMBUS_DisableAlert_IT(SMBUS_HandleTypeDef *hsmbus)
  782. {
  783. /* Enable SMBus alert */
  784. hsmbus->Instance->CR1 &= ~I2C_CR1_ALERTEN;
  785. /* Disable Alert Interrupt */
  786. SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_ALERT);
  787. return HAL_OK;
  788. }
  789. /**
  790. * @brief Check if target device is ready for communication.
  791. * @note This function is used with Memory devices
  792. * @param hsmbus : Pointer to a SMBUS_HandleTypeDef structure that contains
  793. * the configuration information for the specified SMBUS.
  794. * @param DevAddress: Target device address
  795. * @param Trials: Number of trials
  796. * @param Timeout: Timeout duration
  797. * @retval HAL status
  798. */
  799. HAL_StatusTypeDef HAL_SMBUS_IsDeviceReady(SMBUS_HandleTypeDef *hsmbus, uint16_t DevAddress, uint32_t Trials, uint32_t Timeout)
  800. {
  801. uint32_t tickstart = 0U;
  802. __IO uint32_t SMBUS_Trials = 0U;
  803. if(hsmbus->State == HAL_SMBUS_STATE_READY)
  804. {
  805. if(__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_BUSY) != RESET)
  806. {
  807. return HAL_BUSY;
  808. }
  809. /* Process Locked */
  810. __HAL_LOCK(hsmbus);
  811. hsmbus->State = HAL_SMBUS_STATE_BUSY;
  812. hsmbus->ErrorCode = HAL_SMBUS_ERROR_NONE;
  813. do
  814. {
  815. /* Generate Start */
  816. hsmbus->Instance->CR2 = SMBUS_GENERATE_START(hsmbus->Init.AddressingMode,DevAddress);
  817. /* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */
  818. /* Wait until STOPF flag is set or a NACK flag is set*/
  819. tickstart = HAL_GetTick();
  820. while((__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_STOPF) == RESET) && (__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_AF) == RESET) && (hsmbus->State != HAL_SMBUS_STATE_TIMEOUT))
  821. {
  822. if(Timeout != HAL_MAX_DELAY)
  823. {
  824. if((Timeout == 0U) || ((HAL_GetTick() - tickstart) > Timeout))
  825. {
  826. /* Device is ready */
  827. hsmbus->State = HAL_SMBUS_STATE_READY;
  828. /* Process Unlocked */
  829. __HAL_UNLOCK(hsmbus);
  830. return HAL_TIMEOUT;
  831. }
  832. }
  833. }
  834. /* Check if the NACKF flag has not been set */
  835. if (__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_AF) == RESET)
  836. {
  837. /* Wait until STOPF flag is reset */
  838. if(SMBUS_WaitOnFlagUntilTimeout(hsmbus, SMBUS_FLAG_STOPF, RESET, Timeout) != HAL_OK)
  839. {
  840. return HAL_TIMEOUT;
  841. }
  842. /* Clear STOP Flag */
  843. __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_STOPF);
  844. /* Device is ready */
  845. hsmbus->State = HAL_SMBUS_STATE_READY;
  846. /* Process Unlocked */
  847. __HAL_UNLOCK(hsmbus);
  848. return HAL_OK;
  849. }
  850. else
  851. {
  852. /* Wait until STOPF flag is reset */
  853. if(SMBUS_WaitOnFlagUntilTimeout(hsmbus, SMBUS_FLAG_STOPF, RESET, Timeout) != HAL_OK)
  854. {
  855. return HAL_TIMEOUT;
  856. }
  857. /* Clear NACK Flag */
  858. __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_AF);
  859. /* Clear STOP Flag, auto generated with autoend*/
  860. __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_STOPF);
  861. }
  862. /* Check if the maximum allowed number of trials has been reached */
  863. if (SMBUS_Trials++ == Trials)
  864. {
  865. /* Generate Stop */
  866. hsmbus->Instance->CR2 |= I2C_CR2_STOP;
  867. /* Wait until STOPF flag is reset */
  868. if(SMBUS_WaitOnFlagUntilTimeout(hsmbus, SMBUS_FLAG_STOPF, RESET, Timeout) != HAL_OK)
  869. {
  870. return HAL_TIMEOUT;
  871. }
  872. /* Clear STOP Flag */
  873. __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_STOPF);
  874. }
  875. }while(SMBUS_Trials < Trials);
  876. hsmbus->State = HAL_SMBUS_STATE_READY;
  877. /* Process Unlocked */
  878. __HAL_UNLOCK(hsmbus);
  879. return HAL_TIMEOUT;
  880. }
  881. else
  882. {
  883. return HAL_BUSY;
  884. }
  885. }
  886. /**
  887. * @}
  888. */
  889. /** @defgroup SMBUS_IRQ_Handler_and_Callbacks IRQ Handler and Callbacks
  890. * @{
  891. */
  892. /**
  893. * @brief Handle SMBUS event interrupt request.
  894. * @param hsmbus : Pointer to a SMBUS_HandleTypeDef structure that contains
  895. * the configuration information for the specified SMBUS.
  896. * @retval None
  897. */
  898. void HAL_SMBUS_EV_IRQHandler(SMBUS_HandleTypeDef *hsmbus)
  899. {
  900. uint32_t tmpisrvalue = 0U;
  901. /* Use a local variable to store the current ISR flags */
  902. /* This action will avoid a wrong treatment due to ISR flags change during interrupt handler */
  903. tmpisrvalue = SMBUS_GET_ISR_REG(hsmbus);
  904. /* SMBUS in mode Transmitter ---------------------------------------------------*/
  905. if (((SMBUS_CHECK_FLAG(tmpisrvalue, SMBUS_FLAG_TXIS) != RESET) || (SMBUS_CHECK_FLAG(tmpisrvalue, SMBUS_FLAG_TCR) != RESET) || (SMBUS_CHECK_FLAG(tmpisrvalue, SMBUS_FLAG_TC) != RESET) || (SMBUS_CHECK_FLAG(tmpisrvalue, SMBUS_FLAG_STOPF) != RESET) || (SMBUS_CHECK_FLAG(tmpisrvalue, SMBUS_FLAG_AF) != RESET)) && (__HAL_SMBUS_GET_IT_SOURCE(hsmbus, (SMBUS_IT_TCI| SMBUS_IT_STOPI| SMBUS_IT_NACKI | SMBUS_IT_TXI)) != RESET))
  906. {
  907. /* Slave mode selected */
  908. if ((hsmbus->State & HAL_SMBUS_STATE_SLAVE_BUSY_TX) == HAL_SMBUS_STATE_SLAVE_BUSY_TX)
  909. {
  910. SMBUS_Slave_ISR(hsmbus);
  911. }
  912. /* Master mode selected */
  913. else if((hsmbus->State & HAL_SMBUS_STATE_MASTER_BUSY_TX) == HAL_SMBUS_STATE_MASTER_BUSY_TX)
  914. {
  915. SMBUS_Master_ISR(hsmbus);
  916. }
  917. }
  918. /* SMBUS in mode Receiver ----------------------------------------------------*/
  919. if (((SMBUS_CHECK_FLAG(tmpisrvalue, SMBUS_FLAG_RXNE) != RESET) || (SMBUS_CHECK_FLAG(tmpisrvalue, SMBUS_FLAG_TCR) != RESET) || (SMBUS_CHECK_FLAG(tmpisrvalue, SMBUS_FLAG_TC) != RESET) || (SMBUS_CHECK_FLAG(tmpisrvalue, SMBUS_FLAG_STOPF) != RESET) || (SMBUS_CHECK_FLAG(tmpisrvalue, SMBUS_FLAG_AF) != RESET)) && (__HAL_SMBUS_GET_IT_SOURCE(hsmbus, (SMBUS_IT_TCI| SMBUS_IT_STOPI| SMBUS_IT_NACKI | SMBUS_IT_RXI)) != RESET))
  920. {
  921. /* Slave mode selected */
  922. if ((hsmbus->State & HAL_SMBUS_STATE_SLAVE_BUSY_RX) == HAL_SMBUS_STATE_SLAVE_BUSY_RX)
  923. {
  924. SMBUS_Slave_ISR(hsmbus);
  925. }
  926. /* Master mode selected */
  927. else if((hsmbus->State & HAL_SMBUS_STATE_MASTER_BUSY_RX) == HAL_SMBUS_STATE_MASTER_BUSY_RX)
  928. {
  929. SMBUS_Master_ISR(hsmbus);
  930. }
  931. }
  932. /* SMBUS in mode Listener Only --------------------------------------------------*/
  933. if (((SMBUS_CHECK_FLAG(tmpisrvalue, SMBUS_FLAG_ADDR) != RESET) || (SMBUS_CHECK_FLAG(tmpisrvalue, SMBUS_FLAG_STOPF) != RESET) || (SMBUS_CHECK_FLAG(tmpisrvalue, SMBUS_FLAG_AF) != RESET))
  934. && ((__HAL_SMBUS_GET_IT_SOURCE(hsmbus, SMBUS_IT_ADDRI) != RESET) || (__HAL_SMBUS_GET_IT_SOURCE(hsmbus, SMBUS_IT_STOPI) != RESET) || (__HAL_SMBUS_GET_IT_SOURCE(hsmbus, SMBUS_IT_NACKI) != RESET)))
  935. {
  936. if (hsmbus->State == HAL_SMBUS_STATE_LISTEN)
  937. {
  938. SMBUS_Slave_ISR(hsmbus);
  939. }
  940. }
  941. }
  942. /**
  943. * @brief Handle SMBUS error interrupt request.
  944. * @param hsmbus : Pointer to a SMBUS_HandleTypeDef structure that contains
  945. * the configuration information for the specified SMBUS.
  946. * @retval None
  947. */
  948. void HAL_SMBUS_ER_IRQHandler(SMBUS_HandleTypeDef *hsmbus)
  949. {
  950. /* SMBUS Bus error interrupt occurred ------------------------------------*/
  951. if((__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_BERR) != RESET) && (__HAL_SMBUS_GET_IT_SOURCE(hsmbus, SMBUS_IT_ERRI) != RESET))
  952. {
  953. hsmbus->ErrorCode |= HAL_SMBUS_ERROR_BERR;
  954. /* Clear BERR flag */
  955. __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_BERR);
  956. }
  957. /* SMBUS Over-Run/Under-Run interrupt occurred ----------------------------------------*/
  958. if((__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_OVR) != RESET) && (__HAL_SMBUS_GET_IT_SOURCE(hsmbus, SMBUS_IT_ERRI) != RESET))
  959. {
  960. hsmbus->ErrorCode |= HAL_SMBUS_ERROR_OVR;
  961. /* Clear OVR flag */
  962. __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_OVR);
  963. }
  964. /* SMBUS Arbitration Loss error interrupt occurred ------------------------------------*/
  965. if((__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_ARLO) != RESET) && (__HAL_SMBUS_GET_IT_SOURCE(hsmbus, SMBUS_IT_ERRI) != RESET))
  966. {
  967. hsmbus->ErrorCode |= HAL_SMBUS_ERROR_ARLO;
  968. /* Clear ARLO flag */
  969. __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_ARLO);
  970. }
  971. /* SMBUS Timeout error interrupt occurred ---------------------------------------------*/
  972. if((__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_TIMEOUT) != RESET) && (__HAL_SMBUS_GET_IT_SOURCE(hsmbus, SMBUS_IT_ERRI) != RESET))
  973. {
  974. hsmbus->ErrorCode |= HAL_SMBUS_ERROR_BUSTIMEOUT;
  975. /* Clear TIMEOUT flag */
  976. __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_TIMEOUT);
  977. }
  978. /* SMBUS Alert error interrupt occurred -----------------------------------------------*/
  979. if((__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_ALERT) != RESET) && (__HAL_SMBUS_GET_IT_SOURCE(hsmbus, SMBUS_IT_ERRI) != RESET))
  980. {
  981. hsmbus->ErrorCode |= HAL_SMBUS_ERROR_ALERT;
  982. /* Clear ALERT flag */
  983. __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_ALERT);
  984. }
  985. /* SMBUS Packet Error Check error interrupt occurred ----------------------------------*/
  986. if((__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_PECERR) != RESET) && (__HAL_SMBUS_GET_IT_SOURCE(hsmbus, SMBUS_IT_ERRI) != RESET))
  987. {
  988. hsmbus->ErrorCode |= HAL_SMBUS_ERROR_PECERR;
  989. /* Clear PEC error flag */
  990. __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_PECERR);
  991. }
  992. /* Call the Error Callback in case of Error detected */
  993. if((hsmbus->ErrorCode != HAL_SMBUS_ERROR_NONE)&&(hsmbus->ErrorCode != HAL_SMBUS_ERROR_ACKF))
  994. {
  995. /* Do not Reset the HAL state in case of ALERT error */
  996. if((hsmbus->ErrorCode & HAL_SMBUS_ERROR_ALERT) != HAL_SMBUS_ERROR_ALERT)
  997. {
  998. if(((hsmbus->State & HAL_SMBUS_STATE_SLAVE_BUSY_TX) == HAL_SMBUS_STATE_SLAVE_BUSY_TX)
  999. || ((hsmbus->State & HAL_SMBUS_STATE_SLAVE_BUSY_RX) == HAL_SMBUS_STATE_SLAVE_BUSY_RX))
  1000. {
  1001. /* Reset only HAL_SMBUS_STATE_SLAVE_BUSY_XX */
  1002. /* keep HAL_SMBUS_STATE_LISTEN if set */
  1003. hsmbus->PreviousState = HAL_SMBUS_STATE_READY;
  1004. hsmbus->State = HAL_SMBUS_STATE_LISTEN;
  1005. }
  1006. }
  1007. /* Call the Error callback to prevent upper layer */
  1008. HAL_SMBUS_ErrorCallback(hsmbus);
  1009. }
  1010. }
  1011. /**
  1012. * @brief Master Tx Transfer completed callback.
  1013. * @param hsmbus : Pointer to a SMBUS_HandleTypeDef structure that contains
  1014. * the configuration information for the specified SMBUS.
  1015. * @retval None
  1016. */
  1017. __weak void HAL_SMBUS_MasterTxCpltCallback(SMBUS_HandleTypeDef *hsmbus)
  1018. {
  1019. /* Prevent unused argument(s) compilation warning */
  1020. UNUSED(hsmbus);
  1021. /* NOTE : This function should not be modified, when the callback is needed,
  1022. the HAL_SMBUS_MasterTxCpltCallback() could be implemented in the user file
  1023. */
  1024. }
  1025. /**
  1026. * @brief Master Rx Transfer completed callback.
  1027. * @param hsmbus : Pointer to a SMBUS_HandleTypeDef structure that contains
  1028. * the configuration information for the specified SMBUS.
  1029. * @retval None
  1030. */
  1031. __weak void HAL_SMBUS_MasterRxCpltCallback(SMBUS_HandleTypeDef *hsmbus)
  1032. {
  1033. /* Prevent unused argument(s) compilation warning */
  1034. UNUSED(hsmbus);
  1035. /* NOTE : This function should not be modified, when the callback is needed,
  1036. the HAL_SMBUS_MasterRxCpltCallback() could be implemented in the user file
  1037. */
  1038. }
  1039. /** @brief Slave Tx Transfer completed callback.
  1040. * @param hsmbus : Pointer to a SMBUS_HandleTypeDef structure that contains
  1041. * the configuration information for the specified SMBUS.
  1042. * @retval None
  1043. */
  1044. __weak void HAL_SMBUS_SlaveTxCpltCallback(SMBUS_HandleTypeDef *hsmbus)
  1045. {
  1046. /* Prevent unused argument(s) compilation warning */
  1047. UNUSED(hsmbus);
  1048. /* NOTE : This function should not be modified, when the callback is needed,
  1049. the HAL_SMBUS_SlaveTxCpltCallback() could be implemented in the user file
  1050. */
  1051. }
  1052. /**
  1053. * @brief Slave Rx Transfer completed callback.
  1054. * @param hsmbus : Pointer to a SMBUS_HandleTypeDef structure that contains
  1055. * the configuration information for the specified SMBUS.
  1056. * @retval None
  1057. */
  1058. __weak void HAL_SMBUS_SlaveRxCpltCallback(SMBUS_HandleTypeDef *hsmbus)
  1059. {
  1060. /* Prevent unused argument(s) compilation warning */
  1061. UNUSED(hsmbus);
  1062. /* NOTE : This function should not be modified, when the callback is needed,
  1063. the HAL_SMBUS_SlaveRxCpltCallback() could be implemented in the user file
  1064. */
  1065. }
  1066. /**
  1067. * @brief Slave Address Match callback.
  1068. * @param hsmbus : Pointer to a SMBUS_HandleTypeDef structure that contains
  1069. * the configuration information for the specified SMBUS.
  1070. * @param TransferDirection: Master request Transfer Direction (Write/Read)
  1071. * @param AddrMatchCode: Address Match Code
  1072. * @retval None
  1073. */
  1074. __weak void HAL_SMBUS_AddrCallback(SMBUS_HandleTypeDef *hsmbus, uint8_t TransferDirection, uint16_t AddrMatchCode)
  1075. {
  1076. /* Prevent unused argument(s) compilation warning */
  1077. UNUSED(hsmbus);
  1078. UNUSED(TransferDirection);
  1079. UNUSED(AddrMatchCode);
  1080. /* NOTE : This function should not be modified, when the callback is needed,
  1081. the HAL_SMBUS_AddrCallback() could be implemented in the user file
  1082. */
  1083. }
  1084. /**
  1085. * @brief Listen Complete callback.
  1086. * @param hsmbus : Pointer to a SMBUS_HandleTypeDef structure that contains
  1087. * the configuration information for the specified SMBUS.
  1088. * @retval None
  1089. */
  1090. __weak void HAL_SMBUS_ListenCpltCallback(SMBUS_HandleTypeDef *hsmbus)
  1091. {
  1092. /* Prevent unused argument(s) compilation warning */
  1093. UNUSED(hsmbus);
  1094. /* NOTE : This function should not be modified, when the callback is needed,
  1095. the HAL_SMBUS_ListenCpltCallback() could be implemented in the user file
  1096. */
  1097. }
  1098. /**
  1099. * @brief SMBUS error callback.
  1100. * @param hsmbus : Pointer to a SMBUS_HandleTypeDef structure that contains
  1101. * the configuration information for the specified SMBUS.
  1102. * @retval None
  1103. */
  1104. __weak void HAL_SMBUS_ErrorCallback(SMBUS_HandleTypeDef *hsmbus)
  1105. {
  1106. /* Prevent unused argument(s) compilation warning */
  1107. UNUSED(hsmbus);
  1108. /* NOTE : This function should not be modified, when the callback is needed,
  1109. the HAL_SMBUS_ErrorCallback() could be implemented in the user file
  1110. */
  1111. }
  1112. /**
  1113. * @}
  1114. */
  1115. /** @defgroup SMBUS_Exported_Functions_Group3 Peripheral State and Errors functions
  1116. * @brief Peripheral State and Errors functions
  1117. *
  1118. @verbatim
  1119. ===============================================================================
  1120. ##### Peripheral State and Errors functions #####
  1121. ===============================================================================
  1122. [..]
  1123. This subsection permits to get in run-time the status of the peripheral
  1124. and the data flow.
  1125. @endverbatim
  1126. * @{
  1127. */
  1128. /**
  1129. * @brief Return the SMBUS handle state.
  1130. * @param hsmbus : Pointer to a SMBUS_HandleTypeDef structure that contains
  1131. * the configuration information for the specified SMBUS.
  1132. * @retval HAL state
  1133. */
  1134. uint32_t HAL_SMBUS_GetState(SMBUS_HandleTypeDef *hsmbus)
  1135. {
  1136. /* Return SMBUS handle state */
  1137. return hsmbus->State;
  1138. }
  1139. /**
  1140. * @brief Return the SMBUS error code.
  1141. * @param hsmbus : pointer to a SMBUS_HandleTypeDef structure that contains
  1142. * the configuration information for the specified SMBUS.
  1143. * @retval SMBUS Error Code
  1144. */
  1145. uint32_t HAL_SMBUS_GetError(SMBUS_HandleTypeDef *hsmbus)
  1146. {
  1147. return hsmbus->ErrorCode;
  1148. }
  1149. /**
  1150. * @}
  1151. */
  1152. /**
  1153. * @}
  1154. */
  1155. /** @addtogroup SMBUS_Private_Functions SMBUS Private Functions
  1156. * @brief Data transfers Private functions
  1157. * @{
  1158. */
  1159. /**
  1160. * @brief Interrupt Sub-Routine which handle the Interrupt Flags Master Mode.
  1161. * @param hsmbus : Pointer to a SMBUS_HandleTypeDef structure that contains
  1162. * the configuration information for the specified SMBUS.
  1163. * @retval HAL status
  1164. */
  1165. static HAL_StatusTypeDef SMBUS_Master_ISR(SMBUS_HandleTypeDef *hsmbus)
  1166. {
  1167. uint16_t DevAddress;
  1168. /* Process Locked */
  1169. __HAL_LOCK(hsmbus);
  1170. if(__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_AF) != RESET)
  1171. {
  1172. /* Clear NACK Flag */
  1173. __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_AF);
  1174. /* Set corresponding Error Code */
  1175. /* No need to generate STOP, it is automatically done */
  1176. hsmbus->ErrorCode |= HAL_SMBUS_ERROR_ACKF;
  1177. /* Process Unlocked */
  1178. __HAL_UNLOCK(hsmbus);
  1179. /* Call the Error callback to prevent upper layer */
  1180. HAL_SMBUS_ErrorCallback(hsmbus);
  1181. }
  1182. else if(__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_STOPF) != RESET)
  1183. {
  1184. /* Call the corresponding callback to inform upper layer of End of Transfer */
  1185. if(hsmbus->State == HAL_SMBUS_STATE_MASTER_BUSY_TX)
  1186. {
  1187. /* Disable Interrupt */
  1188. SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_TX);
  1189. /* Clear STOP Flag */
  1190. __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_STOPF);
  1191. /* Clear Configuration Register 2 */
  1192. SMBUS_RESET_CR2(hsmbus);
  1193. /* Flush remaining data in Fifo register in case of error occurs before TXEmpty */
  1194. /* Disable the selected SMBUS peripheral */
  1195. __HAL_SMBUS_DISABLE(hsmbus);
  1196. hsmbus->PreviousState = HAL_SMBUS_STATE_READY;
  1197. hsmbus->State = HAL_SMBUS_STATE_READY;
  1198. /* Process Unlocked */
  1199. __HAL_UNLOCK(hsmbus);
  1200. /* REenable the selected SMBUS peripheral */
  1201. __HAL_SMBUS_ENABLE(hsmbus);
  1202. HAL_SMBUS_MasterTxCpltCallback(hsmbus);
  1203. }
  1204. else if(hsmbus->State == HAL_SMBUS_STATE_MASTER_BUSY_RX)
  1205. {
  1206. /* Store Last receive data if any */
  1207. if(__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_RXNE) != RESET)
  1208. {
  1209. /* Read data from RXDR */
  1210. (*hsmbus->pBuffPtr++) = hsmbus->Instance->RXDR;
  1211. if((hsmbus->XferSize > 0U))
  1212. {
  1213. hsmbus->XferSize--;
  1214. hsmbus->XferCount--;
  1215. }
  1216. }
  1217. /* Disable Interrupt */
  1218. SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_RX);
  1219. /* Clear STOP Flag */
  1220. __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_STOPF);
  1221. /* Clear Configuration Register 2 */
  1222. SMBUS_RESET_CR2(hsmbus);
  1223. hsmbus->PreviousState = HAL_SMBUS_STATE_READY;
  1224. hsmbus->State = HAL_SMBUS_STATE_READY;
  1225. /* Process Unlocked */
  1226. __HAL_UNLOCK(hsmbus);
  1227. HAL_SMBUS_MasterRxCpltCallback(hsmbus);
  1228. }
  1229. }
  1230. else if(__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_RXNE) != RESET)
  1231. {
  1232. /* Read data from RXDR */
  1233. (*hsmbus->pBuffPtr++) = hsmbus->Instance->RXDR;
  1234. hsmbus->XferSize--;
  1235. hsmbus->XferCount--;
  1236. }
  1237. else if(__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_TXIS) != RESET)
  1238. {
  1239. /* Write data to TXDR */
  1240. hsmbus->Instance->TXDR = (*hsmbus->pBuffPtr++);
  1241. hsmbus->XferSize--;
  1242. hsmbus->XferCount--;
  1243. }
  1244. else if(__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_TCR) != RESET)
  1245. {
  1246. if((hsmbus->XferSize == 0U)&&(hsmbus->XferCount != 0U))
  1247. {
  1248. DevAddress = (hsmbus->Instance->CR2 & I2C_CR2_SADD);
  1249. if(hsmbus->XferCount > MAX_NBYTE_SIZE)
  1250. {
  1251. SMBUS_TransferConfig(hsmbus, DevAddress, MAX_NBYTE_SIZE, (SMBUS_RELOAD_MODE | (hsmbus->XferOptions & SMBUS_SENDPEC_MODE)), SMBUS_NO_STARTSTOP);
  1252. hsmbus->XferSize = MAX_NBYTE_SIZE;
  1253. }
  1254. else
  1255. {
  1256. hsmbus->XferSize = hsmbus->XferCount;
  1257. SMBUS_TransferConfig(hsmbus,DevAddress,hsmbus->XferSize, hsmbus->XferOptions, SMBUS_NO_STARTSTOP);
  1258. /* If PEC mode is enable, size to transmit should be Size-1 byte, corresponding to PEC byte */
  1259. /* PEC byte is automatically sent by HW block, no need to manage it in Transmit process */
  1260. if(SMBUS_GET_PEC_MODE(hsmbus) != RESET)
  1261. {
  1262. hsmbus->XferSize--;
  1263. hsmbus->XferCount--;
  1264. }
  1265. }
  1266. }
  1267. else if((hsmbus->XferSize == 0U)&&(hsmbus->XferCount == 0U))
  1268. {
  1269. /* Call TxCpltCallback() if no stop mode is set */
  1270. if(SMBUS_GET_STOP_MODE(hsmbus) != SMBUS_AUTOEND_MODE)
  1271. {
  1272. /* Call the corresponding callback to inform upper layer of End of Transfer */
  1273. if(hsmbus->State == HAL_SMBUS_STATE_MASTER_BUSY_TX)
  1274. {
  1275. /* Disable Interrupt */
  1276. SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_TX);
  1277. hsmbus->PreviousState = hsmbus->State;
  1278. hsmbus->State = HAL_SMBUS_STATE_READY;
  1279. /* Process Unlocked */
  1280. __HAL_UNLOCK(hsmbus);
  1281. HAL_SMBUS_MasterTxCpltCallback(hsmbus);
  1282. }
  1283. else if(hsmbus->State == HAL_SMBUS_STATE_MASTER_BUSY_RX)
  1284. {
  1285. SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_RX);
  1286. hsmbus->PreviousState = hsmbus->State;
  1287. hsmbus->State = HAL_SMBUS_STATE_READY;
  1288. /* Process Unlocked */
  1289. __HAL_UNLOCK(hsmbus);
  1290. HAL_SMBUS_MasterRxCpltCallback(hsmbus);
  1291. }
  1292. }
  1293. }
  1294. }
  1295. else if(__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_TC) != RESET)
  1296. {
  1297. if(hsmbus->XferCount == 0U)
  1298. {
  1299. /* Specific use case for Quick command */
  1300. if(hsmbus->pBuffPtr == NULL)
  1301. {
  1302. /* Generate a Stop command */
  1303. hsmbus->Instance->CR2 |= I2C_CR2_STOP;
  1304. }
  1305. /* Call TxCpltCallback() if no stop mode is set */
  1306. else if(SMBUS_GET_STOP_MODE(hsmbus) != SMBUS_AUTOEND_MODE)
  1307. {
  1308. /* No Generate Stop, to permit restart mode */
  1309. /* The stop will be done at the end of transfer, when SMBUS_AUTOEND_MODE enable */
  1310. /* Call the corresponding callback to inform upper layer of End of Transfer */
  1311. if(hsmbus->State == HAL_SMBUS_STATE_MASTER_BUSY_TX)
  1312. {
  1313. /* Disable Interrupt */
  1314. SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_TX);
  1315. hsmbus->PreviousState = hsmbus->State;
  1316. hsmbus->State = HAL_SMBUS_STATE_READY;
  1317. /* Process Unlocked */
  1318. __HAL_UNLOCK(hsmbus);
  1319. HAL_SMBUS_MasterTxCpltCallback(hsmbus);
  1320. }
  1321. else if(hsmbus->State == HAL_SMBUS_STATE_MASTER_BUSY_RX)
  1322. {
  1323. SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_RX);
  1324. hsmbus->PreviousState = hsmbus->State;
  1325. hsmbus->State = HAL_SMBUS_STATE_READY;
  1326. /* Process Unlocked */
  1327. __HAL_UNLOCK(hsmbus);
  1328. HAL_SMBUS_MasterRxCpltCallback(hsmbus);
  1329. }
  1330. }
  1331. }
  1332. }
  1333. /* Process Unlocked */
  1334. __HAL_UNLOCK(hsmbus);
  1335. return HAL_OK;
  1336. }
  1337. /**
  1338. * @brief Interrupt Sub-Routine which handle the Interrupt Flags Slave Mode.
  1339. * @param hsmbus : Pointer to a SMBUS_HandleTypeDef structure that contains
  1340. * the configuration information for the specified SMBUS.
  1341. * @retval HAL status
  1342. */
  1343. static HAL_StatusTypeDef SMBUS_Slave_ISR(SMBUS_HandleTypeDef *hsmbus)
  1344. {
  1345. uint8_t TransferDirection = 0U;
  1346. uint16_t SlaveAddrCode = 0U;
  1347. /* Process Locked */
  1348. __HAL_LOCK(hsmbus);
  1349. if(__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_AF) != RESET)
  1350. {
  1351. /* Check that SMBUS transfer finished */
  1352. /* if yes, normal use case, a NACK is sent by the HOST when Transfer is finished */
  1353. /* Mean XferCount == 0*/
  1354. /* So clear Flag NACKF only */
  1355. if(hsmbus->XferCount == 0U)
  1356. {
  1357. /* Clear NACK Flag */
  1358. __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_AF);
  1359. /* Process Unlocked */
  1360. __HAL_UNLOCK(hsmbus);
  1361. }
  1362. else
  1363. {
  1364. /* if no, error use case, a Non-Acknowledge of last Data is generated by the HOST*/
  1365. /* Clear NACK Flag */
  1366. __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_AF);
  1367. /* Set HAL State to "Idle" State, mean to LISTEN state */
  1368. /* So reset Slave Busy state */
  1369. hsmbus->PreviousState = hsmbus->State;
  1370. hsmbus->State &= ~((uint32_t)HAL_SMBUS_STATE_SLAVE_BUSY_TX);
  1371. hsmbus->State &= ~((uint32_t)HAL_SMBUS_STATE_SLAVE_BUSY_RX);
  1372. /* Disable RX/TX Interrupts, keep only ADDR Interrupt */
  1373. SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_RX | SMBUS_IT_TX);
  1374. /* Set ErrorCode corresponding to a Non-Acknowledge */
  1375. hsmbus->ErrorCode |= HAL_SMBUS_ERROR_ACKF;
  1376. /* Process Unlocked */
  1377. __HAL_UNLOCK(hsmbus);
  1378. /* Call the Error callback to prevent upper layer */
  1379. HAL_SMBUS_ErrorCallback(hsmbus);
  1380. }
  1381. }
  1382. else if(__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_ADDR) != RESET)
  1383. {
  1384. TransferDirection = SMBUS_GET_DIR(hsmbus);
  1385. SlaveAddrCode = SMBUS_GET_ADDR_MATCH(hsmbus);
  1386. /* Disable ADDR interrupt to prevent multiple ADDRInterrupt*/
  1387. /* Other ADDRInterrupt will be treat in next Listen use case */
  1388. __HAL_SMBUS_DISABLE_IT(hsmbus, SMBUS_IT_ADDRI);
  1389. /* Process Unlocked */
  1390. __HAL_UNLOCK(hsmbus);
  1391. /* Call Slave Addr callback */
  1392. HAL_SMBUS_AddrCallback(hsmbus, TransferDirection, SlaveAddrCode);
  1393. }
  1394. else if((__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_RXNE) != RESET) || (__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_TCR) != RESET))
  1395. {
  1396. if( (hsmbus->State & HAL_SMBUS_STATE_SLAVE_BUSY_RX) == HAL_SMBUS_STATE_SLAVE_BUSY_RX)
  1397. {
  1398. /* Read data from RXDR */
  1399. (*hsmbus->pBuffPtr++) = hsmbus->Instance->RXDR;
  1400. hsmbus->XferSize--;
  1401. hsmbus->XferCount--;
  1402. if(hsmbus->XferCount == 1U)
  1403. {
  1404. /* Receive last Byte, can be PEC byte in case of PEC BYTE enabled */
  1405. /* or only the last Byte of Transfer */
  1406. /* So reset the RELOAD bit mode */
  1407. hsmbus->XferOptions &= ~SMBUS_RELOAD_MODE;
  1408. SMBUS_TransferConfig(hsmbus, 0U ,1U , hsmbus->XferOptions, SMBUS_NO_STARTSTOP);
  1409. }
  1410. else if(hsmbus->XferCount == 0U)
  1411. {
  1412. /* Last Byte is received, disable Interrupt */
  1413. SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_RX);
  1414. /* Remove HAL_SMBUS_STATE_SLAVE_BUSY_RX, keep only HAL_SMBUS_STATE_LISTEN */
  1415. hsmbus->PreviousState = hsmbus->State;
  1416. hsmbus->State &= ~((uint32_t)HAL_SMBUS_STATE_SLAVE_BUSY_RX);
  1417. /* Process Unlocked */
  1418. __HAL_UNLOCK(hsmbus);
  1419. /* Call the Rx complete callback to inform upper layer of the end of receive process */
  1420. HAL_SMBUS_SlaveRxCpltCallback(hsmbus);
  1421. }
  1422. else
  1423. {
  1424. /* Set Reload for next Bytes */
  1425. SMBUS_TransferConfig(hsmbus, 0U, 1U, SMBUS_RELOAD_MODE | (hsmbus->XferOptions & SMBUS_SENDPEC_MODE), SMBUS_NO_STARTSTOP);
  1426. /* Ack last Byte Read */
  1427. hsmbus->Instance->CR2 &= ~I2C_CR2_NACK;
  1428. }
  1429. }
  1430. else if( (hsmbus->State & HAL_SMBUS_STATE_SLAVE_BUSY_TX) == HAL_SMBUS_STATE_SLAVE_BUSY_TX)
  1431. {
  1432. if((hsmbus->XferSize == 0U)&&(hsmbus->XferCount != 0U))
  1433. {
  1434. if(hsmbus->XferCount > MAX_NBYTE_SIZE)
  1435. {
  1436. SMBUS_TransferConfig(hsmbus, 0U, MAX_NBYTE_SIZE, (SMBUS_RELOAD_MODE | (hsmbus->XferOptions & SMBUS_SENDPEC_MODE)), SMBUS_NO_STARTSTOP);
  1437. hsmbus->XferSize = MAX_NBYTE_SIZE;
  1438. }
  1439. else
  1440. {
  1441. hsmbus->XferSize = hsmbus->XferCount;
  1442. SMBUS_TransferConfig(hsmbus, 0U, hsmbus->XferSize, hsmbus->XferOptions, SMBUS_NO_STARTSTOP);
  1443. /* If PEC mode is enable, size to transmit should be Size-1 byte, corresponding to PEC byte */
  1444. /* PEC byte is automatically sent by HW block, no need to manage it in Transmit process */
  1445. if(SMBUS_GET_PEC_MODE(hsmbus) != RESET)
  1446. {
  1447. hsmbus->XferSize--;
  1448. hsmbus->XferCount--;
  1449. }
  1450. }
  1451. }
  1452. }
  1453. }
  1454. else if(__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_TXIS) != RESET)
  1455. {
  1456. /* Write data to TXDR only if XferCount not reach "0" */
  1457. /* A TXIS flag can be set, during STOP treatment */
  1458. /* Check if all Data have already been sent */
  1459. /* If it is the case, this last write in TXDR is not sent, correspond to a dummy TXIS event */
  1460. if(hsmbus->XferCount > 0U)
  1461. {
  1462. /* Write data to TXDR */
  1463. hsmbus->Instance->TXDR = (*hsmbus->pBuffPtr++);
  1464. hsmbus->XferCount--;
  1465. hsmbus->XferSize--;
  1466. }
  1467. if(hsmbus->XferCount == 0U)
  1468. {
  1469. /* Last Byte is Transmitted */
  1470. /* Remove HAL_SMBUS_STATE_SLAVE_BUSY_TX, keep only HAL_SMBUS_STATE_LISTEN */
  1471. SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_TX);
  1472. hsmbus->PreviousState = hsmbus->State;
  1473. hsmbus->State &= ~((uint32_t)HAL_SMBUS_STATE_SLAVE_BUSY_TX);
  1474. /* Process Unlocked */
  1475. __HAL_UNLOCK(hsmbus);
  1476. /* Call the Tx complete callback to inform upper layer of the end of transmit process */
  1477. HAL_SMBUS_SlaveTxCpltCallback(hsmbus);
  1478. }
  1479. }
  1480. /* Check if STOPF is set */
  1481. if(__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_STOPF) != RESET)
  1482. {
  1483. if((hsmbus->State & HAL_SMBUS_STATE_LISTEN) == HAL_SMBUS_STATE_LISTEN)
  1484. {
  1485. /* Store Last receive data if any */
  1486. if(__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_RXNE) != RESET)
  1487. {
  1488. /* Read data from RXDR */
  1489. (*hsmbus->pBuffPtr++) = hsmbus->Instance->RXDR;
  1490. if((hsmbus->XferSize > 0U))
  1491. {
  1492. hsmbus->XferSize--;
  1493. hsmbus->XferCount--;
  1494. }
  1495. }
  1496. /* Disable RX and TX Interrupts */
  1497. SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_RX | SMBUS_IT_TX);
  1498. /* Disable ADDR Interrupt */
  1499. SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_ADDR);
  1500. /* Disable Address Acknowledge */
  1501. hsmbus->Instance->CR2 |= I2C_CR2_NACK;
  1502. /* Clear Configuration Register 2 */
  1503. SMBUS_RESET_CR2(hsmbus);
  1504. /* Clear STOP Flag */
  1505. __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_STOPF);
  1506. /* Clear ADDR flag */
  1507. __HAL_SMBUS_CLEAR_FLAG(hsmbus,SMBUS_FLAG_ADDR);
  1508. hsmbus->XferOptions = 0U;
  1509. hsmbus->PreviousState = hsmbus->State;
  1510. hsmbus->State = HAL_SMBUS_STATE_READY;
  1511. /* Process Unlocked */
  1512. __HAL_UNLOCK(hsmbus);
  1513. /* Call the Listen Complete callback, to prevent upper layer of the end of Listen use case */
  1514. HAL_SMBUS_ListenCpltCallback(hsmbus);
  1515. }
  1516. }
  1517. /* Process Unlocked */
  1518. __HAL_UNLOCK(hsmbus);
  1519. return HAL_OK;
  1520. }
  1521. /**
  1522. * @brief Manage the enabling of Interrupts.
  1523. * @param hsmbus : Pointer to a SMBUS_HandleTypeDef structure that contains
  1524. * the configuration information for the specified SMBUS.
  1525. * @param InterruptRequest : Value of @ref SMBUS_Interrupt_configuration_definition.
  1526. * @retval HAL status
  1527. */
  1528. static HAL_StatusTypeDef SMBUS_Enable_IRQ(SMBUS_HandleTypeDef *hsmbus, uint16_t InterruptRequest)
  1529. {
  1530. uint32_t tmpisr = 0U;
  1531. if((InterruptRequest & SMBUS_IT_ALERT) == SMBUS_IT_ALERT)
  1532. {
  1533. /* Enable ERR interrupt */
  1534. tmpisr |= SMBUS_IT_ERRI;
  1535. }
  1536. if((InterruptRequest & SMBUS_IT_ADDR) == SMBUS_IT_ADDR)
  1537. {
  1538. /* Enable ADDR, STOP interrupt */
  1539. tmpisr |= SMBUS_IT_ADDRI | SMBUS_IT_STOPI | SMBUS_IT_NACKI | SMBUS_IT_ERRI;
  1540. }
  1541. if((InterruptRequest & SMBUS_IT_TX) == SMBUS_IT_TX)
  1542. {
  1543. /* Enable ERR, TC, STOP, NACK, RXI interrupt */
  1544. tmpisr |= SMBUS_IT_ERRI | SMBUS_IT_TCI | SMBUS_IT_STOPI | SMBUS_IT_NACKI | SMBUS_IT_TXI;
  1545. }
  1546. if((InterruptRequest & SMBUS_IT_RX) == SMBUS_IT_RX)
  1547. {
  1548. /* Enable ERR, TC, STOP, NACK, TXI interrupt */
  1549. tmpisr |= SMBUS_IT_ERRI | SMBUS_IT_TCI | SMBUS_IT_STOPI | SMBUS_IT_NACKI | SMBUS_IT_RXI;
  1550. }
  1551. /* Enable interrupts only at the end */
  1552. /* to avoid the risk of SMBUS interrupt handle execution before */
  1553. /* all interrupts requested done */
  1554. __HAL_SMBUS_ENABLE_IT(hsmbus, tmpisr);
  1555. return HAL_OK;
  1556. }
  1557. /**
  1558. * @brief Manage the disabling of Interrupts.
  1559. * @param hsmbus : Pointer to a SMBUS_HandleTypeDef structure that contains
  1560. * the configuration information for the specified SMBUS.
  1561. * @param InterruptRequest : Value of @ref SMBUS_Interrupt_configuration_definition.
  1562. * @retval HAL status
  1563. */
  1564. static HAL_StatusTypeDef SMBUS_Disable_IRQ(SMBUS_HandleTypeDef *hsmbus, uint16_t InterruptRequest)
  1565. {
  1566. uint32_t tmpisr = 0U;
  1567. if( ((InterruptRequest & SMBUS_IT_ALERT) == SMBUS_IT_ALERT) && (hsmbus->State == HAL_SMBUS_STATE_READY) )
  1568. {
  1569. /* Disable ERR interrupt */
  1570. tmpisr |= SMBUS_IT_ERRI;
  1571. }
  1572. if((InterruptRequest & SMBUS_IT_TX) == SMBUS_IT_TX)
  1573. {
  1574. /* Disable TC, STOP, NACK, TXI interrupt */
  1575. tmpisr |= SMBUS_IT_TCI | SMBUS_IT_TXI;
  1576. if((SMBUS_GET_ALERT_ENABLED(hsmbus) == RESET)
  1577. && ((hsmbus->State & HAL_SMBUS_STATE_LISTEN) != HAL_SMBUS_STATE_LISTEN))
  1578. {
  1579. /* Disable ERR interrupt */
  1580. tmpisr |= SMBUS_IT_ERRI;
  1581. }
  1582. if((hsmbus->State & HAL_SMBUS_STATE_LISTEN) != HAL_SMBUS_STATE_LISTEN)
  1583. {
  1584. /* Disable STOPI, NACKI */
  1585. tmpisr |= SMBUS_IT_STOPI | SMBUS_IT_NACKI;
  1586. }
  1587. }
  1588. if((InterruptRequest & SMBUS_IT_RX) == SMBUS_IT_RX)
  1589. {
  1590. /* Disable TC, STOP, NACK, RXI interrupt */
  1591. tmpisr |= SMBUS_IT_TCI | SMBUS_IT_RXI;
  1592. if((SMBUS_GET_ALERT_ENABLED(hsmbus) == RESET)
  1593. && ((hsmbus->State & HAL_SMBUS_STATE_LISTEN) != HAL_SMBUS_STATE_LISTEN))
  1594. {
  1595. /* Disable ERR interrupt */
  1596. tmpisr |= SMBUS_IT_ERRI;
  1597. }
  1598. if((hsmbus->State & HAL_SMBUS_STATE_LISTEN) != HAL_SMBUS_STATE_LISTEN)
  1599. {
  1600. /* Disable STOPI, NACKI */
  1601. tmpisr |= SMBUS_IT_STOPI | SMBUS_IT_NACKI;
  1602. }
  1603. }
  1604. if((InterruptRequest & SMBUS_IT_ADDR) == SMBUS_IT_ADDR)
  1605. {
  1606. /* Enable ADDR, STOP interrupt */
  1607. tmpisr |= SMBUS_IT_ADDRI | SMBUS_IT_STOPI | SMBUS_IT_NACKI;
  1608. if(SMBUS_GET_ALERT_ENABLED(hsmbus) == RESET)
  1609. {
  1610. /* Disable ERR interrupt */
  1611. tmpisr |= SMBUS_IT_ERRI;
  1612. }
  1613. }
  1614. /* Disable interrupts only at the end */
  1615. /* to avoid a breaking situation like at "t" time */
  1616. /* all disable interrupts request are not done */
  1617. __HAL_SMBUS_DISABLE_IT(hsmbus, tmpisr);
  1618. return HAL_OK;
  1619. }
  1620. /**
  1621. * @brief Handle SMBUS Communication Timeout.
  1622. * @param hsmbus : Pointer to a SMBUS_HandleTypeDef structure that contains
  1623. * the configuration information for the specified SMBUS.
  1624. * @param Flag: specifies the SMBUS flag to check.
  1625. * @param Status: The new Flag status (SET or RESET).
  1626. * @param Timeout: Timeout duration
  1627. * @retval HAL status
  1628. */
  1629. static HAL_StatusTypeDef SMBUS_WaitOnFlagUntilTimeout(SMBUS_HandleTypeDef *hsmbus, uint32_t Flag, FlagStatus Status, uint32_t Timeout)
  1630. {
  1631. uint32_t tickstart = HAL_GetTick();
  1632. /* Wait until flag is set */
  1633. if(Status == RESET)
  1634. {
  1635. while(__HAL_SMBUS_GET_FLAG(hsmbus, Flag) == RESET)
  1636. {
  1637. /* Check for the Timeout */
  1638. if(Timeout != HAL_MAX_DELAY)
  1639. {
  1640. if((Timeout == 0U) || ((HAL_GetTick() - tickstart) > Timeout))
  1641. {
  1642. hsmbus->PreviousState = hsmbus->State;
  1643. hsmbus->State= HAL_SMBUS_STATE_READY;
  1644. /* Process Unlocked */
  1645. __HAL_UNLOCK(hsmbus);
  1646. return HAL_TIMEOUT;
  1647. }
  1648. }
  1649. }
  1650. }
  1651. else
  1652. {
  1653. while(__HAL_SMBUS_GET_FLAG(hsmbus, Flag) != RESET)
  1654. {
  1655. /* Check for the Timeout */
  1656. if(Timeout != HAL_MAX_DELAY)
  1657. {
  1658. if((Timeout == 0U) || ((HAL_GetTick() - tickstart) > Timeout))
  1659. {
  1660. hsmbus->PreviousState = hsmbus->State;
  1661. hsmbus->State= HAL_SMBUS_STATE_READY;
  1662. /* Process Unlocked */
  1663. __HAL_UNLOCK(hsmbus);
  1664. return HAL_TIMEOUT;
  1665. }
  1666. }
  1667. }
  1668. }
  1669. return HAL_OK;
  1670. }
  1671. /**
  1672. * @brief Handle SMBUSx communication when starting transfer or during transfer (TC or TCR flag are set).
  1673. * @param hsmbus: SMBUS handle.
  1674. * @param DevAddress: specifies the slave address to be programmed.
  1675. * @param Size: specifies the number of bytes to be programmed.
  1676. * This parameter must be a value between 0 and 255.
  1677. * @param Mode: new state of the SMBUS START condition generation.
  1678. * This parameter can be one or a combination of the following values:
  1679. * @arg SMBUS_NO_MODE: No specific mode enabled.
  1680. * @arg SMBUS_RELOAD_MODE: Enable Reload mode.
  1681. * @arg SMBUS_AUTOEND_MODE: Enable Automatic end mode.
  1682. * @arg SMBUS_SOFTEND_MODE: Enable Software end mode and Reload mode.
  1683. * @param Request: new state of the SMBUS START condition generation.
  1684. * This parameter can be one of the following values:
  1685. * @arg SMBUS_NO_STARTSTOP: Don't Generate stop and start condition.
  1686. * @arg SMBUS_GENERATE_STOP: Generate stop condition (Size should be set to 0).
  1687. * @arg SMBUS_GENERATE_START_READ: Generate Restart for read request.
  1688. * @arg SMBUS_GENERATE_START_WRITE: Generate Restart for write request.
  1689. * @retval None
  1690. */
  1691. static void SMBUS_TransferConfig(SMBUS_HandleTypeDef *hsmbus, uint16_t DevAddress, uint8_t Size, uint32_t Mode, uint32_t Request)
  1692. {
  1693. uint32_t tmpreg = 0U;
  1694. /* Check the parameters */
  1695. assert_param(IS_SMBUS_ALL_INSTANCE(hsmbus->Instance));
  1696. assert_param(IS_SMBUS_TRANSFER_MODE(Mode));
  1697. assert_param(IS_SMBUS_TRANSFER_REQUEST(Request));
  1698. /* Get the CR2 register value */
  1699. tmpreg = hsmbus->Instance->CR2;
  1700. /* clear tmpreg specific bits */
  1701. tmpreg &= (uint32_t)~((uint32_t)(I2C_CR2_SADD | I2C_CR2_NBYTES | I2C_CR2_RELOAD | I2C_CR2_AUTOEND | I2C_CR2_RD_WRN | I2C_CR2_START | I2C_CR2_STOP | I2C_CR2_PECBYTE));
  1702. /* update tmpreg */
  1703. tmpreg |= (uint32_t)(((uint32_t)DevAddress & I2C_CR2_SADD) | (((uint32_t)Size << 16U ) & I2C_CR2_NBYTES) | \
  1704. (uint32_t)Mode | (uint32_t)Request);
  1705. /* update CR2 register */
  1706. hsmbus->Instance->CR2 = tmpreg;
  1707. }
  1708. /**
  1709. * @brief Convert SMBUSx OTHER_xxx XferOptions to functionnal XferOptions.
  1710. * @param hsmbus SMBUS handle.
  1711. * @retval None
  1712. */
  1713. static void SMBUS_ConvertOtherXferOptions(SMBUS_HandleTypeDef *hsmbus)
  1714. {
  1715. /* if user set XferOptions to SMBUS_OTHER_FRAME_NO_PEC */
  1716. /* it request implicitly to generate a restart condition */
  1717. /* set XferOptions to SMBUS_FIRST_FRAME */
  1718. if(hsmbus->XferOptions == SMBUS_OTHER_FRAME_NO_PEC)
  1719. {
  1720. hsmbus->XferOptions = SMBUS_FIRST_FRAME;
  1721. }
  1722. /* else if user set XferOptions to SMBUS_OTHER_FRAME_WITH_PEC */
  1723. /* it request implicitly to generate a restart condition */
  1724. /* set XferOptions to SMBUS_FIRST_FRAME | SMBUS_SENDPEC_MODE */
  1725. else if(hsmbus->XferOptions == SMBUS_OTHER_FRAME_WITH_PEC)
  1726. {
  1727. hsmbus->XferOptions = SMBUS_FIRST_FRAME | SMBUS_SENDPEC_MODE;
  1728. }
  1729. /* else if user set XferOptions to SMBUS_OTHER_AND_LAST_FRAME_NO_PEC */
  1730. /* it request implicitly to generate a restart condition */
  1731. /* then generate a stop condition at the end of transfer */
  1732. /* set XferOptions to SMBUS_FIRST_AND_LAST_FRAME_NO_PEC */
  1733. else if(hsmbus->XferOptions == SMBUS_OTHER_AND_LAST_FRAME_NO_PEC)
  1734. {
  1735. hsmbus->XferOptions = SMBUS_FIRST_AND_LAST_FRAME_NO_PEC;
  1736. }
  1737. /* else if user set XferOptions to SMBUS_OTHER_AND_LAST_FRAME_WITH_PEC */
  1738. /* it request implicitly to generate a restart condition */
  1739. /* then generate a stop condition at the end of transfer */
  1740. /* set XferOptions to SMBUS_FIRST_AND_LAST_FRAME_WITH_PEC */
  1741. else if(hsmbus->XferOptions == SMBUS_OTHER_AND_LAST_FRAME_WITH_PEC)
  1742. {
  1743. hsmbus->XferOptions = SMBUS_FIRST_AND_LAST_FRAME_WITH_PEC;
  1744. }
  1745. }
  1746. /**
  1747. * @}
  1748. */
  1749. #endif /* HAL_SMBUS_MODULE_ENABLED */
  1750. /**
  1751. * @}
  1752. */
  1753. /**
  1754. * @}
  1755. */
  1756. /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/