1 /*******************************************************************************
2  * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
3  *
4  * SPDX-License-Identifier: MIT
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to
8  * deal in the Software without restriction, including without limitation the
9  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10  * sell copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in
14  * all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
22  * IN THE SOFTWARE.
23  *
24  * PolarFire SoC Microprocessor Subsystem(MSS) I2C bare metal software driver
25  * public API.
26  *
27  */
28 /*=========================================================================*//**
29   @mainpage PolarFire SoC MSS I2C Bare Metal Driver.
30 
31   ==============================================================================
32   Introduction
33   ==============================================================================
34   The PolarFire SoC Microprocessor Subsystem (MSS) includes two I2C peripherals
35   for serial communication. This driver provides a set of functions for
36   controlling the MSS I2Cs as part of a bare metal system where no
37   operating system is available. The driver can be adapted for use as part of an
38   operating system, but the implementation of the adaptation layer between the
39   driver and the operating system's driver model is outside the scope of this
40   driver.
41 
42   ==============================================================================
43   Hardware Flow Dependencies
44   ==============================================================================
45   The configuration of all features of the MSS I2C peripherals is covered by
46   this driver with the exception of the PolarFire SoC IOMUX configuration.
47   PolarFire SoC allows multiple non-concurrent uses of some external pins
48   through IOMUX configuration. This feature allows optimization of external pin
49   usage by assigning external pins for use by either the microprocessor
50   subsystem or the FPGA fabric. The MSS I2C serial signals are routed through
51   IOMUXs to the PolarFire SoC device external pins. The MSS I2C serial signals
52   may also be routed through IOMUXs to the PolarFire SoC FPGA fabric. For more
53   information on IOMUX, refer to the I/O Configuration section of the PolarFire
54   SoC Microprocessor Subsystem (MSS) User's Guide.
55 
56   The IOMUXs are configured using the PolarFire SoC MSS configurator tool. You
57   must ensure that the MSS I2C peripherals are enabled and configured in the
58   PolarFire SoC MSS configurator if you wish to use them. For more information
59   on IOMUXs, refer to the IOMUX section of the PolarFire SoC Microprocessor
60   Subsystem (MSS) User’s Guide.
61 
62   On PolarFire SoC an AXI switch forms a bus matrix interconnect among
63   multiple masters and multiple slaves. Five RISC-V CPUs connect to the Master
64   ports M10 to M14 of the AXI switch. By default, all the APB peripherals are
65   accessible on AXI-Slave 5 of the AXI switch via the AXI to AHB and AHB to APB
66   bridges (referred as main APB bus). However, to support logical separation in
67   the Asymmetric Multi-Processing (AMP) mode of operation, the APB peripherals
68   can alternatively be accessed on the AXI-Slave 6 via the AXI to AHB and AHB
69   to APB bridges (referred as the AMP APB bus).
70 
71   Application must make sure that the desired I2C instance is connected
72   appropriately on the desired APB bus by configuring the PolarFire SoC system
73   registers (SYSREG) as per the application need and that the appropriate data
74   structures are provided to this driver as parameter to the functions provided
75   by this driver.
76 
77   The base address and register addresses are defined in this driver as
78   constants. The interrupt number assignment for the MSS I2C peripherals are
79   defined as constants in the MPFS HAL. You must ensure that the latest MPFS
80   HAL is included in the project settings of the SoftConsole tool chain and
81   that it is generated into your project.
82 
83   ==============================================================================
84   Theory of Operation
85   ==============================================================================
86   The MSS I2C driver functions are grouped into the following categories:
87     - Initialization and configuration functions
88     - Interrupt control
89     - I2C slave address configuration
90     - I2C master operations - functions to handle write, read and write-read
91                               transactions
92     - I2C slave operations  - functions to handle write, read and write-read
93                               transactions
94     - Mixed master and slave operations
95     - SMBus interface configuration and control
96 
97   --------------------------------
98   Initialization and Configuration
99   --------------------------------
100     The MSS I2C driver is initialized through a call to the MSS_I2C_init()
101     function. This function takes the MSS I2C's configuration as parameters.
102     The MSS_I2C_init() function must be called before any other MSS I2C driver
103     functions can be called. The first parameter of the MSS_I2C_init() function
104     is a pointer to one of four global data structures used by the driver to
105     store state information for each MSS I2C. A pointer to these data
106     structures is also used as the first parameter to any of the driver
107     functions to identify which MSS I2C will be used by the called function.
108     The names of these data structures are
109               g_mss_i2c0_lo
110               g_mss_i2c0_hi
111               g_mss_i2c1_lo
112               g_mss_i2c1_hi
113     Therefore any call to an MSS I2C driver function should be of the form
114     MSS_I2C_function_name( &g_mss_i2c0_lo, ... ) or
115     MSS_I2C_function_name( &g_mss_i2c1_lo, ... ).
116 
117     The MSS_I2C_init() function call for each MSS I2C also takes the I2C serial
118     address assigned to the MSS I2C and the serial clock divider to be used to
119     generate its I2C clock as configuration parameters.
120 
121   --------------------------------
122   Interrupt Control
123   --------------------------------
124     The MSS I2C driver is interrupt driven and it enables and disables the
125     generation of INT interrupts by MSS I2C at various times when it is
126     operating. The driver automatically handles MSS I2C interrupts internally,
127     including enabling, disabling and clearing MSS I2C interrupts in the
128     RISC-V interrupt controller when required.
129 
130     The function MSS_I2C_register_write_handler() is used to register a write
131     handler function with the MSS I2C driver that it calls on completion of an
132     I2C write transaction by the MSS I2C slave. It is your responsibility to
133     create and register the implementation of this handler function that
134     processes or triggers the processing of the received data.
135 
136     The SMBSUS and SMBALERT interrupts are related to the SMBus interface and
137     are enabled and disabled through MSS_I2C_enable_smbus_irq() and
138     MSS_I2C_disable_smbus_irq() respectively. It is your responsibility to
139     create interrupt handler functions in your application to get the desired
140     response for the SMBus interrupts.
141 
142   --------------------------------
143   I2C Slave Address Configuration
144   --------------------------------
145     The PolarFire SoC MSS I2C can respond to two slave addresses:
146       - Slave address - This is the address that is used for accessing an MSS
147                         I2C peripheral when it acts as a slave in I2C
148                         transactions. You must configure the slave address via
149                         MSS_I2C_init().
150 
151       - General call address - An MSS I2C slave can be configured to respond to
152                         a broadcast command by a master transmitting the general
153                         call address of 0x00. Use the MSS_I2C_set_gca() function
154                         to enable the slave to respond to the general call
155                         address. If the I2C slave is not required to respond to
156                         the general call address, disable this address by
157                         calling MSS_I2C_clear_gca().
158 
159   --------------------------------
160   Transaction Types
161   --------------------------------
162     The MSS I2C driver is designed to handle three types of I2C transactions:
163       Write transactions
164       Read transactions
165       Write-read transactions
166 
167     Write transaction
168       The master I2C device initiates a write transaction by sending a START bit
169       as soon as the bus becomes free. The START bit is followed by the 7-bit
170       serial address of the target slave device followed by the read/write bit
171       indicating the direction of the transaction. The slave acknowledges the
172       receipt of its address with an acknowledge bit. The master sends data one
173       byte at a time to the slave, which must acknowledge the receipt of each
174       byte for the next byte to be sent. The master sends a STOP bit to complete
175       the transaction. The slave can abort the transaction by replying with a
176       non-acknowledge bit instead of an acknowledge bit.
177 
178       The application programmer can choose not to send a STOP bit at the end of
179       the transaction causing the next transaction to begin with a repeated
180       START bit.
181 
182     Read transaction
183       The master I2C device initiates a read transaction by sending a START bit
184       as soon as the bus becomes free. The START bit is followed by the 7-bit
185       serial address of the target slave device followed by the read/write bit
186       indicating the direction of the transaction. The slave acknowledges the
187       receipt of its slave address with an acknowledge bit. The slave sends data
188       one byte at a time to the master, which must acknowledge receipt of each
189       byte for the next byte to be sent. The master sends a non-acknowledge bit
190       following the last byte it wishes to read followed by a STOP bit.
191 
192       The application programmer can choose not to send a STOP bit at the end of
193       the transaction causing the next transaction to begin with a repeated
194       START bit.
195 
196     Write-read transaction
197       The write-read transaction is a combination of a write transaction
198       immediately followed by a read transaction. There is no STOP bit between
199       the write and read phases of a write-read transaction. A repeated START
200       bit is sent between the write and read phases.
201 
202       Whilst the write handler is being executed, the slave holds the clock line
203       low to stretch the clock until the response is ready.
204 
205       The write-read transaction is typically used to send a command or offset
206       in the write transaction specifying the logical data to be transferred
207       during the read phase.
208 
209       The application programmer can choose not to send a STOP bit at the end of
210       the transaction causing the next transaction to begin with a repeated
211       START bit.
212 
213   --------------------------------
214   Master Operations
215   --------------------------------
216     The application can use the MSS_I2C_write(), MSS_I2C_read() and
217     MSS_I2C_write_read() functions to initiate an I2C bus transaction. The
218     application can then wait for the transaction to complete using the
219     MSS_I2C_wait_complete() function or poll the status of the I2C transaction
220     using the MSS_I2C_get_status() function until it returns a value different
221     from MSS_I2C_IN_PROGRESS or register a call back function using
222     MSS_I2C_register_transfer_completion_handler() to notify the completion of
223     the previously initiated I2C transfer. The MSS_I2C_system_tick() function
224     can be used to set a time base for the MSS_I2C_wait_complete() function's
225     time out delay.
226 
227   --------------------------------
228   Slave Operations
229   --------------------------------
230     The configuration of the MSS I2C driver to operate as an I2C slave requires
231     the use of the following functions:
232        - MSS_I2C_set_slave_tx_buffer()
233        - MSS_I2C_set_slave_rx_buffer()
234        - MSS_I2C_set_slave_mem_offset_length()
235        - MSS_I2C_register_write_handler()
236        - MSS_I2C_enable_slave()
237 
238     Use of all functions is not required if the slave I2C does not need to
239     support all types of I2C read transactions. The subsequent sections list the
240     functions that must be used to support each transaction type.
241 
242     Responding to read transactions
243       The following functions are used to configure the MSS I2C driver to
244       respond to I2C read transactions:
245         - MSS_I2C_set_slave_tx_buffer()
246         - MSS_I2C_enable_slave()
247 
248       The function MSS_I2C_set_slave_tx_buffer() specifies the data buffer that
249       will be transmitted when the I2C slave is the target of an I2C read
250       transaction. It is then up to the application to manage the content of
251       that buffer to control the data that will be transmitted to the I2C master
252       as a result of the read transaction.
253 
254       The function MSS_I2C_enable_slave() enables the MSS I2C hardware instance
255       to respond to I2C transactions. It must be called after the MSS I2C driver
256       has been configured to respond to the required transaction types.
257 
258     Responding to write transactions
259       The following functions are used to configure the MSS I2C driver to
260       respond to I2C write transactions:
261         - MSS_I2C_set_slave_rx_buffer()
262         - MSS_I2C_register_write_handler()
263         - MSS_I2C_enable_slave()
264 
265       The function MSS_I2C_set_slave_rx_buffer() specifies the data buffer that
266       will be used to store the data received by the I2C slave when it is the
267       target an I2C  write transaction.
268 
269       The function MSS_I2C_register_write_handler() specifies the handler
270       function that must be called on completion of the I2C write transaction.
271       It is this handler function that will process or trigger the processing of
272       the received data.
273 
274       The function MSS_I2C_enable_slave() enables the MSS I2C hardware instance
275       to respond to I2C transactions. It must be called after the MSS I2C driver
276       has been configured to respond to the required transaction types.
277 
278     Responding to write-read transactions
279       The following functions are used to configure the MSS I2C driver to
280       respond to write-read transactions:
281         - MSS_I2C_set_slave_mem_offset_length()
282         - MSS_I2C_set_slave_tx_buffer()
283         - MSS_I2C_set_slave_rx_buffer()
284         - MSS_I2C_register_write_handler()
285         - MSS_I2C_enable_slave()
286 
287       The function MSS_I2C_set_slave_mem_offset_length() specifies the number of
288       bytes expected by the I2C slave during the write phase of the write-read
289       transaction.
290 
291       The function MSS_I2C_set_slave_tx_buffer() specifies the data that will be
292       transmitted to the I2C master during the read phase of the write-read
293       transaction. The value received by the I2C slave during the write phase of
294       the transaction will be used as an index into the transmit buffer
295       specified by this function to decide which part of the transmit buffer
296       will be transmitted to the I2C master as part of the read phase of the
297       write-read transaction.
298 
299       The function MSS_I2C_set_slave_rx_buffer() specifies the data buffer that
300       will be used to store the data received by the I2C slave during the write
301       phase of the write-read transaction. This buffer must be at least large
302       enough to accommodate the number of bytes specified through the
303       MSS_I2C_set_slave_mem_offset_length() function.
304 
305       The function MSS_I2C_register_write_handler() can optionally be used to
306       specify a handler function that is called on completion of the write phase
307       of the I2C write-read transaction. If a handler function is registered, it
308       is responsible for processing the received data in the slave receive
309       buffer and populating the slave transmit buffer with the data that will be
310       transmitted to the I2C master as part of the read phase of the write-read
311       transaction.
312 
313       The function MSS_I2C_enable_slave() enables the MSS I2C hardware instance
314       to respond to I2C transactions. It must be called after the MSS I2C driver
315       has been configured to respond to the required transaction types.
316 
317   --------------------------------
318   Mixed Master and Slave Operations
319   --------------------------------
320       The MSS I2C device supports mixed master and slave operations. If the MSS
321       I2C slave has a transaction in progress and your application attempts to
322       begin a master mode transaction, the MSS I2C driver queues the master mode
323       transaction until the bus is released and the MSS I2C can switch to master
324       mode and acquire the bus. The MSS I2C master then starts the previously
325       pended transaction.
326 
327   --------------------------------
328   SMBus Interface Configuration and Control
329   --------------------------------
330     The MSS I2C driver enables the MSS I2C peripheral�s SMBus functionality
331     using the MSS_I2C_smbus_init() function.
332 
333     The MSS_I2C_suspend_smbus_slave() function is used, with a master mode MSS
334     I2C, to force slave devices on the SMBus to enter their power-down/suspend
335     mode.
336 
337     The MSS_I2C_resume_smbus_slave() function is used to end the suspend
338     operation on the SMBus.
339 
340     The MSS_I2C_reset_smbus() function is used, with a master mode MSS I2C, to
341     force all devices on the SMBus to reset their SMBUs interface.
342 
343     The MSS_I2C_set_smsbus_alert() function is used, by a slave mode MSS I2C, to
344     force communication with the SMBus master. Once communications with the
345     master is initiated, the MSS_I2C_clear_smsbus_alert() function is used to
346     clear the alert condition.
347 
348     The MSS_I2C_enable_smbus_irq() and MSS_I2C_disable_smbus_irq() functions are
349     used to enable and disable the SMBSUS and SMBALERT SMBus interrupts.
350 
351  *//*=========================================================================*/
352 
353 #ifndef MSS_I2C_H_
354 #define MSS_I2C_H_
355 
356 #ifdef __cplusplus
357 extern "C" {
358 #endif
359 
360 #include <stddef.h>
361 #include <stdint.h>
362 
363 /*-------------------------------------------------------------------------*//**
364   The mss_i2c_clock_divider_t type is used to specify the divider to be applied
365   to the MSS I2C PCLK or BCLK signal in order to generate the I2C clock.
366   The MSS_I2C_BCLK_DIV_8 value selects a clock frequency based on division of
367   BCLK, all other values select a clock frequency based on division of PCLK.
368  */
369 typedef enum mss_i2c_clock_divider {
370     MSS_I2C_PCLK_DIV_256 = 0u,
371     MSS_I2C_PCLK_DIV_224,
372     MSS_I2C_PCLK_DIV_192,
373     MSS_I2C_PCLK_DIV_160,
374     MSS_I2C_PCLK_DIV_960,
375     MSS_I2C_PCLK_DIV_120,
376     MSS_I2C_PCLK_DIV_60,
377     MSS_I2C_BCLK_DIV_8
378 } mss_i2c_clock_divider_t;
379 
380 /*-------------------------------------------------------------------------*//**
381   MSS_I2C_RELEASE_BUS
382   =================================
383   The MSS_I2C_RELEASE_BUS constant is used to specify the options parameter to
384   functions MSS_I2C_read(), MSS_I2C_write() and MSS_I2C_write_read() to indicate
385   that a STOP bit must be generated at the end of the I2C transaction to release
386   the bus.
387  */
388 #define MSS_I2C_RELEASE_BUS        0x00u
389 
390 /*-------------------------------------------------------------------------*//**
391   MSS_I2C_HOLD_BUS
392   =================================
393   The MSS_I2C_HOLD_BUS constant is used to specify the options parameter to
394   functions MSS_I2C_read(), MSS_I2C_write() and MSS_I2C_write_read() to
395   indicate that a STOP bit must not be generated at the end of the I2C
396   transaction in order to retain the bus ownership. This causes the next
397   transaction to begin with a repeated START bit and no STOP bit between the
398   transactions.
399  */
400 #define MSS_I2C_HOLD_BUS           0x01u
401 
402 /*-------------------------------------------------------------------------*//**
403   MSS_I2C_SMBALERT_IRQ
404   =================================
405   The MSS_I2C_SMBALERT_IRQ constant is used with the MSS_I2C_enable_smbus_irq()
406   and MSS_I2C_disable_smbus_irq() functions to enable or disable the SMBus
407   SMBALERT interrupt.
408  */
409 #define MSS_I2C_SMBALERT_IRQ       0x01u
410 
411 /*-------------------------------------------------------------------------*//**
412   MSS_I2C_SMBSUS_IRQ
413   =================================
414  The MSS_I2C_SMBSUS_IRQ constant is used with the MSS_I2C_enable_smbus_irq() and
415  MSS_I2C_disable_smbus_irq() functions to enable or disable the SMBus
416  SMBSUS interrupt.
417  */
418 #define MSS_I2C_SMBSUS_IRQ         0x02u
419 
420 /*-------------------------------------------------------------------------*//**
421   MSS_I2C_NO_TIMEOUT
422   =================================
423   The MSS_I2C_NO_TIMEOUT constant is used to specify the timeout_ms parameter to
424   the MSS_I2C_wait_complete() function to indicate that the function must not
425   time out while waiting for the I2C transaction to complete.
426  */
427 #define MSS_I2C_NO_TIMEOUT         0u
428 
429 /*-------------------------------------------------------------------------*//**
430   The mss_i2c_status_t type is used to report the status of I2C transactions.
431  */
432 typedef enum mss_i2c_status
433 {
434     MSS_I2C_SUCCESS = 0u,
435     MSS_I2C_IN_PROGRESS,
436     MSS_I2C_FAILED,
437     MSS_I2C_TIMED_OUT
438 } mss_i2c_status_t;
439 
440 /*-------------------------------------------------------------------------*//**
441   The mss_i2c_slave_handler_ret_t type is used by slave write handler functions
442   to indicate whether or not the received data buffer should be released.
443  */
444 typedef enum mss_i2c_slave_handler_ret {
445     MSS_I2C_REENABLE_SLAVE_RX = 0u,
446     MSS_I2C_PAUSE_SLAVE_RX = 1u
447 } mss_i2c_slave_handler_ret_t;
448 
449 typedef struct mss_i2c_instance mss_i2c_instance_t ;
450 
451 /*-------------------------------------------------------------------------*//**
452   Transfer completion call back handler functions prototype.
453   This defines the function prototype that must be followed by MSS I2C master
454   and slave transfer completion handler functions. These functions are registered
455   with the MSS I2C driver through the MSS_I2C_register_transfer_completion_handler()
456   function.
457 
458   Declaring and Implementing transfer completion call back functions:
459     Transfer complete call back function should follow the following prototype:
460     void i2c0_completion_handler
461     (
462         mss_i2c_instance_t *instance,
463         mss_i2c_status_t status
464     )
465 
466     The instance parameter is a pointer to the mss_i2c_instance_t for which this
467     transfer completion callback handler has been declared.
468 
469     The status parameter provides the status information of the current transfer
470     completion such as transfer successful or any error occurred.
471 
472   }
473   */
474 typedef void (*mss_i2c_transfer_completion_t)( mss_i2c_instance_t *instance, mss_i2c_status_t status);
475 
476 /*-------------------------------------------------------------------------*//**
477   Slave write handler functions prototype.
478   ------------------------------------------------------------------------------
479   This defines the function prototype that must be followed by MSS I2C slave
480   write handler functions. These functions are registered with the MSS I2C
481   driver through the MSS_I2C_register_write_handler() function.
482 
483   Declaring and Implementing Slave Write Handler Functions:
484     Slave write handler functions should follow the following prototype:
485     mss_i2c_slave_handler_ret_t write_handler
486     (
487         mss_i2c_instance_t *instance, uint8_t * data, uint16_t size
488     );
489 
490     The instance parameter is a pointer to the mss_i2c_instance_t for which this
491     slave write handler has been declared.
492 
493     The data parameter is a pointer to a buffer (received data buffer) holding
494     the data written to the MSS I2C slave.
495 
496     Defining the macro MSS_I2C_INCLUDE_SLA_IN_RX_PAYLOAD causes the driver to
497     insert the actual address used to access the slave as the first byte in the
498     buffer. This allows applications tailor their response based on the actual
499     address used to access the slave (primary address or GCA).
500 
501     The size parameter is the number of bytes held in the received data buffer.
502     Handler functions must return one of the following values:
503         MSS_I2C_REENABLE_SLAVE_RX
504         MSS_I2C_PAUSE_SLAVE_RX.
505 
506     If the handler function returns MSS_I2C_REENABLE_SLAVE_RX, the driver
507     releases the received data buffer and allows further I2C write transactions
508     to the MSS I2C slave to take place.
509 
510     If the handler function returns MSS_I2C_PAUSE_SLAVE_RX, the MSS I2C slave
511     responds to subsequent write requests with a non-acknowledge bit (NACK),
512     until the received data buffer content has been processed by some other part
513     of the software application.
514 
515     A call to MSS_I2C_enable_slave() is required at some point after
516     returning MSS_I2C_PAUSE_SLAVE_RX in order to release the received data
517     buffer so it can be used to store data received by subsequent I2C write
518     transactions.
519  */
520 typedef mss_i2c_slave_handler_ret_t (*mss_i2c_slave_wr_handler_t)( mss_i2c_instance_t *instance, uint8_t * data, uint16_t size);
521 
522 typedef struct
523 {
524     volatile uint8_t  CTRL;
525     uint8_t  RESERVED0;
526     uint16_t RESERVED1;
527     uint8_t  STATUS;
528     uint8_t  RESERVED2;
529     uint16_t RESERVED3;
530     volatile  uint8_t  DATA;
531     uint8_t  RESERVED4;
532     uint16_t RESERVED5;
533     volatile uint8_t  ADDR;
534     uint8_t  RESERVED6;
535     uint16_t RESERVED7;
536     volatile uint8_t  SMBUS;
537     uint8_t  RESERVED8;
538     uint16_t RESERVED9;
539     volatile uint8_t  FREQ;
540     uint8_t  RESERVED10;
541     uint16_t RESERVED11;
542     volatile uint8_t  GLITCHREG;
543     uint8_t  RESERVED12;
544     uint16_t RESERVED13;
545     volatile uint8_t  SLAVE1_ADDR;
546     uint8_t  RESERVED14;
547     uint16_t RESERVED15;
548 } I2C_TypeDef;
549 
550 /*-------------------------------------------------------------------------*//**
551   mss_i2c_instance_t
552   ------------------------------------------------------------------------------
553   There is one instance of this structure for each of the MSS I2Cs. Instances
554   of this structure are used to identify a specific MSS I2C. A pointer to an
555   instance of the mss_i2c_instance_t structure is passed as the first parameter
556   to MSS I2C driver functions to identify which MSS I2C should perform the
557   requested operation.
558  */
559 struct mss_i2c_instance
560 {
561     uint_fast8_t ser_address;
562 
563     /* Transmit related info:*/
564     uint_fast8_t target_addr;
565 
566     /* Current transaction type (WRITE, READ, RANDOM_READ)*/
567     uint8_t transaction;
568 
569     uint_fast16_t random_read_addr;
570 
571     uint8_t options;
572 
573     /* I2C hardware instance identification */
574     PLIC_IRQn_Type  irqn;
575     I2C_TypeDef * hw_reg;
576 
577     /* Master TX INFO: */
578     const uint8_t * master_tx_buffer;
579     uint_fast16_t master_tx_size;
580     uint_fast16_t master_tx_idx;
581     uint_fast8_t dir;
582 
583     /* Master RX INFO: */
584     uint8_t * master_rx_buffer;
585     uint_fast16_t master_rx_size;
586     uint_fast16_t master_rx_idx;
587 
588     /* Master Status */
589     volatile mss_i2c_status_t master_status;
590     uint32_t master_timeout_ms;
591 
592     /* Slave TX INFO */
593     const uint8_t * slave_tx_buffer;
594     uint_fast16_t slave_tx_size;
595     uint_fast16_t slave_tx_idx;
596 
597     /* Slave RX INFO */
598     uint8_t * slave_rx_buffer;
599     uint_fast16_t slave_rx_size;
600     uint_fast16_t slave_rx_idx;
601 
602     /* Slave Status */
603     volatile mss_i2c_status_t slave_status;
604 
605     /* Slave data: */
606     uint_fast8_t slave_mem_offset_length;
607     mss_i2c_slave_wr_handler_t slave_write_handler;
608     uint8_t is_slave_enabled;
609 
610     /* Transfer completion handler. */
611     mss_i2c_transfer_completion_t transfer_completion_handler;
612 
613     /* User  specific data */
614     void *p_user_data ;
615 
616     /* I2C bus status */
617     uint8_t bus_status;
618 
619     /* Is transaction pending flag */
620     uint8_t is_transaction_pending;
621 
622     /* I2C Pending transaction */
623     uint8_t pending_transaction;
624 };
625 
626 /*-------------------------------------------------------------------------*//**
627   This instance of mss_i2c_instance_t holds all data related to the operations
628   performed by MSS I2C 0 connected on main APB bus. The MSS_I2C_init()function
629   initializes this structure. A pointer to g_mss_i2c0_lo is passed as the first
630   parameter to MSS I2C driver functions to indicate that MSS I2C 0 should
631   perform the requested operation.
632 */
633 extern mss_i2c_instance_t g_mss_i2c0_lo;
634 
635 /*-------------------------------------------------------------------------*//**
636   This instance of mss_i2c_instance_t holds all data related to the operations
637   performed by MSS I2C 1 connected on main APB bus. The MSS_I2C_init()function
638   initializes this structure. A pointer to g_mss_i2c1_lo is passed as the first
639   parameter to MSS I2C driver functions to indicate that MSS I2C 1 should
640   perform the requested operation.
641 */
642 extern mss_i2c_instance_t g_mss_i2c1_lo;
643 
644 /*-------------------------------------------------------------------------*//**
645   This instance of mss_i2c_instance_t holds all data related to the operations
646   performed by MSS I2C 0 connected on main APB bus. The MSS_I2C_init()function
647   initializes this structure. A pointer to g_mss_i2c0_lo is passed as the first
648   parameter to MSS I2C driver functions to indicate that MSS I2C 0 should
649   perform the requested operation.
650 */
651 extern mss_i2c_instance_t g_mss_i2c0_hi;
652 
653 /*-------------------------------------------------------------------------*//**
654   This instance of mss_i2c_instance_t holds all data related to the operations
655   performed by MSS I2C 1 connected on main APB bus. The MSS_I2C_init()function
656   initializes this structure. A pointer to g_mss_i2c1_lo is passed as the first
657   parameter to MSS I2C driver functions to indicate that MSS I2C 1 should
658   perform the requested operation.
659 */
660 extern mss_i2c_instance_t g_mss_i2c1_hi;
661 
662 /*-------------------------------------------------------------------------*//**
663   MSS I2C initialization routine.
664   ------------------------------------------------------------------------------
665   structures of one of the PolarFire SoC MSS I2Cs.
666   ------------------------------------------------------------------------------
667   The MSS_I2C_init() function initializes and configures hardware and data
668   structures of one of the PolarFire SoC MSS I2Cs.
669 
670   @param this_i2c
671     The this_i2c parameter is a pointer to an mss_i2c_instance_t structure
672     identifying the MSS I2C hardware block to be initialized. There are four
673     such data structures, g_mss_i2c0_lo and g_mss_i2c1_lo, associated with MSS
674     I2C 0 and MSS I2C 1 when they are connected on the AXI switch slave 5 (main
675     APB bus) and g_mss_i2c0_hi and g_mss_i2c1_hi, associated with MSS I2C 0 to
676     MSS I2C 1 when they are connected on the AXI switch slave 6 (AMP APB bus).
677     This parameter must point to one of these four global data structure defined
678     within I2C driver.
679 
680   @param ser_address
681     This parameter sets the I2C serial address for the MSS I2C peripheral being
682     initialized. It is the I2C bus address to which the MSS I2C instance
683     responds. MSS I2C peripherals can operate in master or slave mode and the
684     serial address is significant only in the case of I2C slave mode. In master
685     mode, MSS I2C does not require a serial address and the value of this
686     parameter is not important. If you do not intend to use the I2C device in
687     slave mode, then any dummy slave address value can be provided to this
688     parameter. However, in systems where the MSS I2C may be expected to switch
689     from master mode to slave mode, it is advisable to initialize the MSS I2C
690     device with a valid serial slave address.
691     You need to call the MSS_I2C_init() function whenever it is required to
692     change the slave address as there is no separate function to set the slave
693     address of an I2C device.
694 
695   @param ser_clock_speed
696     This parameter sets the I2C serial clock frequency. It selects the divider
697     that will be used to generate the serial clock from the APB PCLK or from
698     the BCLK. It can be one of the following:
699         MSS_I2C_PCLK_DIV_256
700         MSS_I2C_PCLK_DIV_224
701         MSS_I2C_PCLK_DIV_192
702         MSS_I2C_PCLK_DIV_160
703         MSS_I2C_PCLK_DIV_960
704         MSS_I2C_PCLK_DIV_120
705         MSS_I2C_PCLK_DIV_60
706         MSS_I2C_BCLK_DIV_8
707 
708     Note: serial_clock_speed value is not critical for devices that only operate
709           as slaves and can be set to any of the above values.
710 
711   @return
712     This function does not return a value.
713 
714   Example:
715   @code
716     #define SLAVE_SER_ADDR_0   0x10u
717     #define SLAVE_SER_ADDR_1   0x20u
718     void system_init( void )
719     {
720         MSS_I2C_init( &g_mss_i2c0_lo, SLAVE_SER_ADDR_0, MSS_I2C_PCLK_DIV_256 );
721         MSS_I2C_init( &g_mss_i2c1_lo, SLAVE_SER_ADDR_1, MSS_I2C_PCLK_DIV_256 );
722     }
723   @endcode
724 */
725 void MSS_I2C_init
726 (
727     mss_i2c_instance_t * this_i2c,
728     uint8_t ser_address,
729     mss_i2c_clock_divider_t ser_clock_speed
730 );
731 
732 /*******************************************************************************
733  *******************************************************************************
734  *
735  *                           Master specific functions
736  *
737  * The following functions are only used within an I2C master's implementation.
738  */
739 
740 /*-------------------------------------------------------------------------*//**
741   I2C master write function.
742   ------------------------------------------------------------------------------
743   This function initiates an I2C master write transaction. This function returns
744   immediately after initiating the transaction. The content of the write buffer
745   passed as parameter should not be modified until the write transaction
746   completes. It also means that the memory allocated for the write buffer should
747   not be freed or should not go out of scope before the write completes.
748   You can check for the write transaction completion using the MSS_I2C_status()
749   function. Additionally, driver will notify write transaction completion if
750   callback function is registered.
751   ------------------------------------------------------------------------------
752   @param this_i2c:
753     The this_i2c parameter is a pointer to an mss_i2c_instance_t structure
754     identifying the MSS I2C hardware block to be initialized. There are four
755     such data structures, g_mss_i2c0_lo and g_mss_i2c1_lo, associated with MSS
756     I2C 0 and MSS I2C 1 when they are connected on the AXI switch slave 5 (main
757     APB bus) and g_mss_i2c0_hi and g_mss_i2c1_hi, associated with MSS I2C 0 to
758     MSS I2C 1 when they are connected on the AXI switch slave 6 (AMP APB bus).
759     This parameter must point to one of these four global data structure defined
760     within I2C driver.
761 
762   @param serial_addr:
763     This parameter specifies the serial address of the target I2C device.
764 
765   @param write_buffer:
766     This parameter is a pointer to a buffer holding the data to be written to
767     the target I2C device.
768     Care must be taken not to release the memory used by this buffer before the
769     write transaction completes. For example, it is not appropriate to return
770     from a function allocating this buffer as an auto array variable before the
771     write transaction completes as this would result in the buffer's memory
772     being de-allocated from the stack when the function returns. This memory
773     could then be subsequently reused and modified causing unexpected data to be
774     written to the target I2C device.
775 
776   @param write_size:
777     Number of bytes held in the write_buffer to be written to the target I2C
778     device.
779 
780  @param options:
781     The options parameter is used to indicate if the I2C bus should be released
782     on completion of the write transaction. Using the MSS_I2C_RELEASE_BUS
783     constant for the options parameter causes a STOP bit to be generated at the
784     end of the write transaction causing the bus to be released for other I2C
785     devices to use. Using the MSS_I2C_HOLD_BUS constant as options parameter
786     prevents a STOP bit from being generated at the end of the write
787     transaction, preventing other I2C devices from initiating a bus transaction.
788 
789   @return
790     This function does not return a value.
791 
792   Example:
793   @code
794     #define I2C_DUMMY_ADDR   0x10u
795     #define DATA_LENGTH      16u
796 
797     uint8_t  tx_buffer[DATA_LENGTH];
798     uint8_t  write_length = DATA_LENGTH;
799 
800     void main( void )
801     {
802         uint8_t  target_slave_addr = 0x12;
803         mss_i2c_status_t status;
804 
805         MSS_I2C_init( &g_mss_i2c0_lo, I2C_DUMMY_ADDR, MSS_I2C_PCLK_DIV_256 );
806 
807         MSS_I2C_write( &g_mss_i2c0_lo, target_slave_addr, tx_buffer,
808                        write_length,
809                        MSS_I2C_RELEASE_BUS );
810 
811         status = MSS_I2C_wait_complete( &g_mss_i2c0_lo, MSS_I2C_NO_TIMEOUT );
812     }
813   @endcode
814  */
815 void MSS_I2C_write
816 (
817     mss_i2c_instance_t * this_i2c,
818     uint8_t serial_addr,
819     const uint8_t * write_buffer,
820     uint16_t write_size,
821     uint8_t options
822 );
823 
824 /*-------------------------------------------------------------------------*//**
825   I2C master read.
826   ------------------------------------------------------------------------------
827   This function initiates an I2C master read transaction. This function returns
828   immediately after initiating the transaction.
829   The content of the read buffer passed as the parameter should not be modified
830   until the read transaction completes. It also means that the memory allocated
831   for the read buffer should not be freed or should not go out of scope before
832   the read completes. You can check for the read transaction completion using
833   the MSS_I2C_status() function. Additionally, driver will notify read
834   transaction completion, if callback function is registered.
835   ------------------------------------------------------------------------------
836   @param this_i2c:
837     The this_i2c parameter is a pointer to an mss_i2c_instance_t structure
838     identifying the MSS I2C hardware block to be initialized. There are four
839     such data structures, g_mss_i2c0_lo and g_mss_i2c1_lo, associated with MSS
840     I2C 0 and MSS I2C 1 when they are connected on the AXI switch slave 5 (main
841     APB bus) and g_mss_i2c0_hi and g_mss_i2c1_hi, associated with MSS I2C 0 to
842     MSS I2C 1 when they are connected on the AXI switch slave 6 (AMP APB bus).
843     This parameter must point to one of these four global data structure defined
844     within I2C driver..
845 
846   @param serial_addr:
847     This parameter specifies the serial address of the target I2C device.
848 
849   @param read_buffer
850     This is a pointer to a buffer where the data received from the target device
851     will be stored.
852     Care must be taken not to release the memory used by this buffer before the
853     read transaction completes. For example, it is not appropriate to return
854     from a function allocating this buffer as an auto array variable before the
855     read transaction completes as this would result in the buffer's memory being
856     de-allocated from the stack when the function returns. This memory could
857     then be subsequently reallocated resulting in the read transaction
858     corrupting the newly allocated memory.
859 
860   @param read_size:
861     This parameter specifies the number of bytes to read from the target device.
862     This size must not exceed the size of the read_buffer buffer.
863 
864   @param options:
865     The options parameter is used to indicate if the I2C bus should be released
866     on completion of the read transaction. Using the MSS_I2C_RELEASE_BUS
867     constant for the options parameter causes a STOP bit to be generated at the
868     end of the read transaction causing the bus to be released for other I2C
869     devices to use. Using the MSS_I2C_HOLD_BUS constant as options parameter
870     prevents a STOP bit from being generated at the end of the read transaction,
871     preventing other I2C devices from initiating a bus transaction.
872 
873   @return
874     This function does not return a value.
875 
876   Example:
877   @code
878     #define I2C_DUMMY_ADDR   0x10u
879     #define DATA_LENGTH      16u
880 
881     uint8_t  rx_buffer[DATA_LENGTH];
882     uint8_t  read_length = DATA_LENGTH ;
883 
884     void main( void )
885     {
886         uint8_t  target_slave_addr = 0x12;
887         mss_i2c_status_t status;
888 
889         MSS_I2C_init( &g_mss_i2c0_lo, I2C_DUMMY_ADDR, MSS_I2C_PCLK_DIV_256 );
890 
891         MSS_I2C_read( &g_mss_i2c0_lo, target_slave_addr, rx_buffer, read_length,
892                       MSS_I2C_RELEASE_BUS );
893 
894         status = MSS_I2C_wait_complete( &g_mss_i2c0_lo, MSS_I2C_NO_TIMEOUT );
895     }
896   @endcode
897  */
898 void MSS_I2C_read
899 (
900     mss_i2c_instance_t * this_i2c,
901     uint8_t serial_addr,
902     uint8_t * read_buffer,
903     uint16_t read_size,
904     uint8_t options
905 );
906 
907 /*-------------------------------------------------------------------------*//**
908   I2C master write-read
909   ------------------------------------------------------------------------------
910   This function initiates an I2C write-read transaction where data is first
911   written to the target device before issuing a restart condition and changing
912   the direction of the I2C transaction in order to read from the target device.
913 
914   The same warnings about buffer allocation in MSS_I2C_write() and
915   MSS_I2C_read() apply to this function.
916   ------------------------------------------------------------------------------
917   @param this_i2c:
918     The this_i2c parameter is a pointer to an mss_i2c_instance_t structure
919     identifying the MSS I2C hardware block to be initialized. There are four
920     such data structures, g_mss_i2c0_lo and g_mss_i2c1_lo, associated with MSS
921     I2C 0 and MSS I2C 1 when they are connected on the AXI switch slave 5 (main
922     APB bus) and g_mss_i2c0_hi and g_mss_i2c1_hi, associated with MSS I2C 0 to
923     MSS I2C 1 when they are connected on the AXI switch slave 6 (AMP APB bus).
924     This parameter must point to one of these four global data structure
925     defined within I2C driver.
926 
927   @param serial_addr:
928     This parameter specifies the serial address of the target I2C device.
929 
930   @param addr_offset:
931     This parameter is a pointer to the buffer containing the data that will be
932     sent to the slave during the write phase of the write-read transaction.
933     This data is typically used to specify an address offset specifying to the
934     I2C slave device what data it must return during the read phase of the
935     write-read transaction.
936 
937   @param offset_size:
938     This parameter specifies the number of offset bytes to be written during the
939     write phase of the write-read transaction. This is typically the size of the
940     buffer pointed to by the addr_offset parameter.
941 
942   @param read_buffer:
943     This parameter is a pointer to the buffer where the data read from the I2C
944     slave will be stored.
945 
946   @param read_size:
947     This parameter specifies the number of bytes to read from the target I2C
948     slave device. This size must not exceed the size of the buffer pointed to by
949     the read_buffer parameter.
950 
951   @param options:
952     The options parameter is used to indicate if the I2C bus should be released
953     on completion of the write-read transaction. Using the MSS_I2C_RELEASE_BUS
954     constant for the options parameter causes a STOP bit to be generated at the
955     end of the write-read transaction causing the bus to be released for other
956     I2C devices to use. Using the MSS_I2C_HOLD_BUS constant as options parameter
957     prevents a STOP bit from being generated at the end of the write-read
958     transaction, preventing other I2C devices from initiating a bus transaction.
959 
960   @return
961     This function does not return a value.
962 
963   Example:
964   @code
965     #define I2C_DUMMY_ADDR   0x10u
966     #define TX_LENGTH        16u
967     #define RX_LENGTH        8u
968 
969     uint8_t  rx_buffer[RX_LENGTH];
970     uint8_t  read_length = RX_LENGTH;
971     uint8_t  tx_buffer[TX_LENGTH];
972     uint8_t  write_length = TX_LENGTH;
973 
974     void main( void )
975     {
976         uint8_t  target_slave_addr = 0x12;
977         mss_i2c_status_t status;
978 
979         MSS_I2C_init( &g_mss_i2c0_lo, I2C_DUMMY_ADDR, MSS_I2C_PCLK_DIV_256 );
980 
981         MSS_I2C_write_read( &g_mss_i2c0_lo, target_slave_addr, tx_buffer,
982                             write_length, rx_buffer, read_length,
983                             MSS_I2C_RELEASE_BUS );
984 
985         status = MSS_I2C_wait_complete( &g_mss_i2c0_lo, MSS_I2C_NO_TIMEOUT );
986     }
987   @endcode
988  */
989 void MSS_I2C_write_read
990 (
991     mss_i2c_instance_t * this_i2c,
992     uint8_t serial_addr,
993     const uint8_t * addr_offset,
994     uint16_t offset_size,
995     uint8_t * read_buffer,
996     uint16_t read_size,
997     uint8_t options
998 );
999 
1000 /*-------------------------------------------------------------------------*//**
1001   I2C status
1002   ------------------------------------------------------------------------------
1003   This function indicates the current state of an MSS I2C instance.
1004   ------------------------------------------------------------------------------
1005   @param this_i2c:
1006     The this_i2c parameter is a pointer to an mss_i2c_instance_t structure
1007     identifying the MSS I2C hardware block to be initialized. There are four
1008     such data structures, g_mss_i2c0_lo and g_mss_i2c1_lo, associated with MSS
1009     I2C 0 and MSS I2C 1 when they are connected on the AXI switch slave 5 (main
1010     APB bus) and g_mss_i2c0_hi and g_mss_i2c1_hi, associated with MSS I2C 0 to
1011     MSS I2C 1 when they are connected on the AXI switch slave 6 (AMP APB bus).
1012     This parameter must point to one of these four global data structure defined
1013     within I2C driver.
1014 
1015   @return
1016     The return value indicates the current state of a MSS I2C instance or the
1017     outcome of the previous transaction if no transaction is in progress.
1018     Possible return values are:
1019       MSS_I2C_SUCCESS
1020         The last I2C transaction has completed successfully.
1021       MSS_I2C_IN_PROGRESS
1022         There is an I2C transaction in progress.
1023       MSS_I2C_FAILED
1024         The last I2C transaction failed.
1025       MSS_I2C_TIMED_OUT
1026         The request has failed to complete in the allotted time.
1027 
1028   Example:
1029   @code
1030     while( MSS_I2C_IN_PROGRESS == MSS_I2C_get_status( &g_mss_i2c0_lo ) )
1031     {
1032         // Do something useful while waiting for I2C operation to complete
1033         our_i2c_busy_task();
1034     }
1035 
1036     if( MSS_I2C_SUCCESS != MSS_I2C_get_status( &g_mss_i2c0_lo ) )
1037     {
1038         // Something went wrong...
1039         our_i2c_error_recovery( &g_mss_i2c0_lo );
1040     }
1041   @endcode
1042  */
1043 mss_i2c_status_t MSS_I2C_get_status
1044 (
1045     mss_i2c_instance_t * this_i2c
1046 );
1047 
1048 /*-------------------------------------------------------------------------*//**
1049   Wait for I2C transaction completion.
1050   ------------------------------------------------------------------------------
1051   This function waits for the current I2C transaction to complete. The return
1052   value indicates whether the last I2C transaction was successful or not.
1053   ------------------------------------------------------------------------------
1054   @param this_i2c:
1055     The this_i2c parameter is a pointer to an mss_i2c_instance_t structure
1056     identifying the MSS I2C hardware block to be initialized. There are four
1057     such data structures, g_mss_i2c0_lo and g_mss_i2c1_lo, associated with MSS
1058     I2C 0 and MSS I2C 1 when they are connected on the AXI switch slave 5 (main
1059     APB bus) and g_mss_i2c0_hi and g_mss_i2c1_hi, associated with MSS I2C 0 to
1060     MSS I2C 1 when they are connected on the AXI switch slave 6 (AMP APB bus).
1061     This parameter must point to one of these four global data structure defined
1062     within I2C driver.
1063 
1064   @param timeout_ms:
1065     The timeout_ms parameter specifies the delay within which the current I2C
1066     transaction is expected to complete. The time out delay is given in
1067     milliseconds. MSS_I2C_wait_complete() will return MSS_I2C_TIMED_OUT if the
1068     current transaction does not complete before the time out delay expires.
1069     Alternatively, the timeout_ms parameter can be set to MSS_I2C_NO_TIMEOUT to
1070     indicate that the MSS_I2C_wait_complete() function must not time out.
1071     Note: If you set the timeout_ms parameter to a value other than
1072           MSS_I2C_NO_TIMEOUT, you must call the MSS_I2C_system_tick() function
1073           from an implementation of the SysTick timer interrupt
1074           service routine SysTick_Handler() in your application. Otherwise
1075           the time out will not take effect and the MSS_I2C_wait_complete()
1076           function will not time out.
1077 
1078   @return
1079     The return value indicates the outcome of the last I2C transaction. It can
1080     be one of the following:
1081       MSS_I2C_SUCCESS
1082         The last I2C transaction has completed successfully.
1083       MSS_I2C_FAILED
1084         The last I2C transaction failed.
1085       MSS_I2C_TIMED_OUT
1086         The last transaction failed to complete within the time out delay
1087         specified by the timeout_ms parameter.
1088 
1089   Example:
1090   @code
1091     #define I2C_DUMMY_ADDR   0x10u
1092     #define DATA_LENGTH      16u
1093 
1094     uint8_t  rx_buffer[DATA_LENGTH];
1095     uint8_t  read_length = DATA_LENGTH;
1096 
1097     void main( void )
1098     {
1099         uint8_t  target_slave_addr = 0x12;
1100         mss_i2c_status_t status;
1101 
1102         // Initialize MSS I2C peripheral
1103         MSS_I2C_init( &g_mss_i2c0_lo, I2C_DUMMY_ADDR, MSS_I2C_PCLK_DIV_256 );
1104 
1105         // Read data from slave.
1106         MSS_I2C_read( &g_mss_i2c0_lo, target_slave_addr, rx_buffer, read_length,
1107                        MSS_I2C_RELEASE_BUS );
1108 
1109         // Wait for completion and record the outcome
1110         status = MSS_I2C_wait_complete( &g_mss_i2c0_lo, MSS_I2C_NO_TIMEOUT );
1111     }
1112   @endcode
1113  */
1114 mss_i2c_status_t MSS_I2C_wait_complete
1115 (
1116     mss_i2c_instance_t * this_i2c,
1117     uint32_t timeout_ms
1118 );
1119 
1120 /*-------------------------------------------------------------------------*//**
1121   Time out delay expiration.
1122   ------------------------------------------------------------------------------
1123   This function is used to control the expiration of the time out delay
1124   specified as a parameter to the MSS_I2C_wait_complete() function. It must be
1125   called from the interrupt service routine of a periodic interrupt source such
1126   as the SysTick timer interrupt. It takes the period of the interrupt
1127   source as its ms_since_last_tick parameter and uses it as the time base for
1128   the MSS_I2C_wait_complete() function's time out delay.
1129 
1130   Note: This function does not need to be called if the MSS_I2C_wait_complete()
1131         function is called with a timeout_ms value of MSS_I2C_NO_TIMEOUT.
1132   Note: If this function is not called then the MSS_I2C_wait_complete() function
1133         will behave as if its timeout_ms was specified as MSS_I2C_NO_TIMEOUT and
1134         it will not time out.
1135   Note: If this function is being called from an interrupt handler (e.g SysTick)
1136         it is important that the calling interrupt have a lower priority than
1137         the MSS I2C interrupt(s) to ensure any updates to shared data are
1138         protected.
1139   ------------------------------------------------------------------------------
1140   @param this_i2c:
1141     The this_i2c parameter is a pointer to an mss_i2c_instance_t structure
1142     identifying the MSS I2C hardware block to be initialized. There are four
1143     such data structures, g_mss_i2c0_lo and g_mss_i2c1_lo, associated with MSS
1144     I2C 0 and MSS I2C 1 when they are connected on the AXI switch slave 5 (main
1145     APB bus) and g_mss_i2c0_hi and g_mss_i2c1_hi, associated with MSS I2C 0 to
1146     MSS I2C 1 when they are connected on the AXI switch slave 6 (AMP APB bus).
1147     This parameter must point to one of these four global data structure defined
1148     within I2C driver.
1149 
1150   @param ms_since_last_tick:
1151     The ms_since_last_tick parameter specifies the number of milliseconds that
1152     elapsed since the last call to MSS_I2C_system_tick(). This parameter would
1153     typically be a constant specifying the interrupt rate of a timer used to
1154     generate system ticks.
1155 
1156   @return
1157     This function does not return a value.
1158 
1159   Example:
1160     The example below shows an example of how the MSS_I2C_system_tick() function
1161     would be called in a RISC-V based system. MSS_I2C_system_tick() is called
1162     for each MSS I2C peripheral from the RISC-V SysTick timer interrupt
1163     service routine. The SysTick is configured to generate an interrupt every 10
1164     milliseconds in the example below.
1165   @code
1166     #define SYSTICK_INTERVAL_MS 10
1167 
1168     void SysTick_Handler(void)
1169     {
1170         MSS_I2C_system_tick(&g_mss_i2c0_lo, SYSTICK_INTERVAL_MS);
1171         MSS_I2C_system_tick(&g_mss_i2c1_lo, SYSTICK_INTERVAL_MS);
1172     }
1173   @endcode
1174  */
1175 void MSS_I2C_system_tick
1176 (
1177     mss_i2c_instance_t * this_i2c,
1178     uint32_t ms_since_last_tick
1179 );
1180 
1181 /*******************************************************************************
1182  *******************************************************************************
1183  *
1184  *                           Slave specific functions
1185  *
1186  * The following functions are only used within the implementation of an I2C
1187  * slave device.
1188  */
1189 
1190 /*-------------------------------------------------------------------------*//**
1191   I2C slave transmit buffer configuration.
1192   ------------------------------------------------------------------------------
1193   This function specifies the memory buffer holding the data that will be sent
1194   to the I2C master when this MSS I2C instance is the target of an I2C read or
1195   write-read transaction.
1196   ------------------------------------------------------------------------------
1197   @param this_i2c:
1198     The this_i2c parameter is a pointer to an mss_i2c_instance_t structure
1199     identifying the MSS I2C hardware block to be initialized. There are four
1200     such data structures, g_mss_i2c0_lo and g_mss_i2c1_lo, associated with MSS
1201     I2C 0 and MSS I2C 1 when they are connected on the AXI switch slave 5 (main
1202     APB bus) and g_mss_i2c0_hi and g_mss_i2c1_hi, associated with MSS I2C 0 to
1203     MSS I2C 1 when they are connected on the AXI switch slave 6 (AMP APB bus).
1204     This parameter must point to one of these four global data structure defined
1205     within I2C driver.
1206 
1207   @param tx_buffer:
1208     This parameter is a pointer to the memory buffer holding the data to be
1209     returned to the I2C master when this MSS I2C instance is the target of an
1210     I2C read or write-read transaction.
1211 
1212   @param tx_size:
1213     Size of the transmit buffer pointed to by the tx_buffer parameter.
1214 
1215   @return
1216     This function does not return a value.
1217 
1218   Example:
1219   @code
1220     #define SLAVE_SER_ADDR         0x10u
1221     #define SLAVE_TX_BUFFER_SIZE   10u
1222 
1223     uint8_t g_slave_tx_buffer[SLAVE_TX_BUFFER_SIZE] = { 1, 2, 3, 4, 5,
1224                                                         6, 7, 8, 9, 10 };
1225 
1226     void main( void )
1227     {
1228         // Initialize the MSS I2C driver with its I2C serial address and serial
1229         // clock divider.
1230         MSS_I2C_init( &g_mss_i2c0_lo, SLAVE_SER_ADDR, MSS_I2C_PCLK_DIV_256 );
1231 
1232         // Specify the transmit buffer containing the data that will be
1233         // returned to the master during read and write-read transactions.
1234         MSS_I2C_set_slave_tx_buffer( &g_mss_i2c0_lo, g_slave_tx_buffer,
1235                                      sizeof(g_slave_tx_buffer) );
1236     }
1237   @endcode
1238  */
1239 void MSS_I2C_set_slave_tx_buffer
1240 (
1241     mss_i2c_instance_t * this_i2c,
1242     const uint8_t * tx_buffer,
1243     uint16_t tx_size
1244 );
1245 
1246 /*-------------------------------------------------------------------------*//**
1247   I2C slave receive buffer configuration.
1248   ------------------------------------------------------------------------------
1249   This function specifies the memory buffer that will be used by the MSS I2C
1250   instance to receive data when it is a slave. This buffer is the memory where
1251   data will be stored when the MSS I2C is the target of an I2C master write
1252   transaction (i.e. when it is the slave).
1253   ------------------------------------------------------------------------------
1254   @param this_i2c:
1255     The this_i2c parameter is a pointer to an mss_i2c_instance_t structure
1256     identifying the MSS I2C hardware block to be initialized. There are four
1257     such data structures, g_mss_i2c0_lo and g_mss_i2c1_lo, associated with MSS
1258     I2C 0 and MSS I2C 1 when they are connected on the AXI switch slave 5 (main
1259     APB bus) and g_mss_i2c0_hi and g_mss_i2c1_hi, associated with MSS I2C 0 to
1260     MSS I2C 1 when they are connected on the AXI switch slave 6 (AMP APB bus).
1261     This parameter must point to one of these four global data structure defined
1262     within I2C driver.
1263 
1264   @param rx_buffer:
1265     This parameter is a pointer to the memory buffer allocated by the caller
1266     software to be used as a slave receive buffer.
1267 
1268   @param rx_size:
1269     Size of the slave receive buffer. This is the amount of memory that is
1270     allocated to the buffer pointed to by rx_buffer.
1271     Note:   This buffer size indirectly specifies the maximum I2C write
1272             transaction length this MSS I2C instance can be the target of.
1273             This is because this MSS I2C instance responds to further received
1274             bytes with a non-acknowledge bit (NACK) as soon as it�s receive
1275             buffer is full. This causes the write transaction to fail.
1276 
1277   @return none.
1278 
1279   Example:
1280   @code
1281     #define SLAVE_SER_ADDR     0x10u
1282     #define SLAVE_RX_BUFFER_SIZE 10u
1283 
1284     uint8_t g_slave_rx_buffer[SLAVE_RX_BUFFER_SIZE];
1285 
1286     void main( void )
1287     {
1288         // Initialize the MSS I2C driver with its I2C serial address and
1289         // serial clock divider.
1290         MSS_I2C_init( &g_mss_i2c0_lo, SLAVE_SER_ADDR, MSS_I2C_PCLK_DIV_256 );
1291 
1292         // Specify the buffer used to store the data written by the I2C master.
1293         MSS_I2C_set_slave_rx_buffer( &g_mss_i2c0_lo, g_slave_rx_buffer,
1294                                      sizeof(g_slave_rx_buffer) );
1295     }
1296   @endcode
1297  */
1298 void MSS_I2C_set_slave_rx_buffer
1299 (
1300     mss_i2c_instance_t * this_i2c,
1301     uint8_t * rx_buffer,
1302     uint16_t rx_size
1303 );
1304 
1305 /*-------------------------------------------------------------------------*//**
1306   I2C slave memory offset length configuration.
1307   ------------------------------------------------------------------------------
1308   This function is used as part of the configuration of an MSS I2C instance for
1309   operation as a slave supporting write-read transactions. It specifies the
1310   number of bytes expected as part of the write phase of a write-read
1311   transaction. The bytes received during the write phase of a write-read
1312   transaction are interpreted as an offset into the slave's transmit buffer.
1313   This allows random access into the I2C slave transmit buffer from a remote
1314   I2C master.
1315   ------------------------------------------------------------------------------
1316   @param this_i2c:
1317     The this_i2c parameter is a pointer to an mss_i2c_instance_t structure
1318     identifying the MSS I2C hardware block to be initialized. There are four
1319     such data structures, g_mss_i2c0_lo and g_mss_i2c1_lo, associated with MSS
1320     I2C 0 and MSS I2C 1 when they are connected on the AXI switch slave 5 (main
1321     APB bus) and g_mss_i2c0_hi and g_mss_i2c1_hi, associated with MSS I2C 0 to
1322     MSS I2C 1 when they are connected on the AXI switch slave 6 (AMP APB bus).
1323     This parameter must point to one of these four global data structure defined
1324     within I2C driver.
1325 
1326   @param offset_length:
1327     The offset_length parameter configures the number of bytes to be interpreted
1328     by the MSS I2C slave as a memory offset value during the write phase of
1329     write-read transactions. The maximum value for the offset_length parameter
1330     is two. The value of offset_length has the following effect on the
1331     interpretation of the received data.
1332 
1333       If offset_length is 0, the offset into the transmit buffer is fixed at 0.
1334 
1335       If offset_length is 1, a single byte of received data is interpreted as an
1336       unsigned 8 bit offset value in the range 0 to 255.
1337 
1338       If offset_length is 2, 2 bytes of received data are interpreted as an
1339       unsigned 16 bit offset value in the range 0 to 65535. The first byte
1340       received in this case provides the high order bits of the offset and
1341       the second byte provides the low order bits.
1342 
1343     If the number of bytes received does not match the non 0 value of
1344     offset_length the transmit buffer offset is set to 0.
1345 
1346   @return none.
1347 
1348   Example:
1349   @code
1350     #define SLAVE_SER_ADDR       0x10u
1351     #define SLAVE_TX_BUFFER_SIZE 10u
1352 
1353     uint8_t g_slave_tx_buffer[SLAVE_TX_BUFFER_SIZE] = { 1, 2, 3, 4, 5,
1354                                                         6, 7, 8, 9, 10 };
1355 
1356     void main( void )
1357     {
1358         // Initialize the MSS I2C driver with its I2C serial address and serial
1359         // clock divider.
1360         MSS_I2C_init( &g_mss_i2c0_lo, SLAVE_SER_ADDR, MSS_I2C_PCLK_DIV_256 );
1361         MSS_I2C_set_slave_tx_buffer( &g_mss_i2c0_lo, g_slave_tx_buffer,
1362                                      sizeof(g_slave_tx_buffer) );
1363         MSS_I2C_set_slave_mem_offset_length( &g_mss_i2c0_lo, 1 );
1364     }
1365   @endcode
1366  */
1367 void MSS_I2C_set_slave_mem_offset_length
1368 (
1369     mss_i2c_instance_t * this_i2c,
1370     uint8_t offset_length
1371 );
1372 
1373 /*-------------------------------------------------------------------------*//**
1374   I2C write handler registration.
1375   ------------------------------------------------------------------------------
1376   Register the function that is called to process the data written to this MSS
1377   I2C instance when it is the slave in an I2C write transaction.
1378   Note: If a write handler is registered, it is called on completion of the
1379         write phase of a write-read transaction and responsible for processing
1380         the received data in the slave receive buffer and populating the slave
1381         transmit buffer with the data that will be transmitted to the I2C master
1382         as part of the read phase of the write-read transaction. If a write
1383         handler is not registered, the write data of a write read transaction is
1384         interpreted as an offset into the slave�s transmit buffer and handled by
1385         the driver.
1386   ------------------------------------------------------------------------------
1387   @param this_i2c:
1388     The this_i2c parameter is a pointer to an mss_i2c_instance_t structure
1389     identifying the MSS I2C hardware block to be initialized. There are four
1390     such data structures, g_mss_i2c0_lo and g_mss_i2c1_lo, associated with MSS
1391     I2C 0 and MSS I2C 1 when they are connected on the AXI switch slave 5 (main
1392     APB bus) and g_mss_i2c0_hi and g_mss_i2c1_hi, associated with MSS I2C 0 to
1393     MSS I2C 1 when they are connected on the AXI switch slave 6 (AMP APB bus).
1394     This parameter must point to one of these four global data structure defined
1395     within I2C driver.
1396 
1397   @param handler:
1398     Pointer to the function that will process the I2C write request.
1399 
1400   @return none.
1401 
1402   Example:
1403   @code
1404     #define SLAVE_SER_ADDR       0x10u
1405     #define SLAVE_TX_BUFFER_SIZE 10u
1406 
1407     uint8_t g_slave_tx_buffer[SLAVE_TX_BUFFER_SIZE] = { 1, 2, 3, 4, 5,
1408                                                        6, 7, 8, 9, 10 };
1409 
1410     local function prototype
1411     void slave_write_handler
1412     (
1413         mss_i2c_instance_t * this_i2c,
1414         uint8_t * p_rx_data,
1415         uint16_t rx_size
1416     );
1417 
1418     void main( void )
1419     {
1420         // Initialize the MSS I2C driver with its I2C serial address and serial
1421         // clock divider.
1422         MSS_I2C_init( &g_mss_i2c0_lo, SLAVE_SER_ADDR, MSS_I2C_PCLK_DIV_256 );
1423         MSS_I2C_set_slave_tx_buffer( &g_mss_i2c0_lo, g_slave_tx_buffer,
1424                                      sizeof(g_slave_tx_buffer) );
1425         MSS_I2C_set_slave_mem_offset_length( &g_mss_i2c0_lo, 1 );
1426         MSS_I2C_register_write_handler( &g_mss_i2c0_lo, slave_write_handler );
1427     }
1428   @endcode
1429  */
1430 void MSS_I2C_register_write_handler
1431 (
1432     mss_i2c_instance_t * this_i2c,
1433     mss_i2c_slave_wr_handler_t handler
1434 );
1435 
1436 /*-------------------------------------------------------------------------*//**
1437   I2C slave enable.
1438   ------------------------------------------------------------------------------
1439   This function enables slave mode operation for an MSS I2C peripheral. It
1440   enables the MSS I2C slave to receive data when it is the target of an I2C
1441   read, write or write-read transaction.
1442   ------------------------------------------------------------------------------
1443   @param this_i2c:
1444     The this_i2c parameter is a pointer to an mss_i2c_instance_t structure
1445     identifying the MSS I2C hardware block to be initialized. There are four
1446     such data structures, g_mss_i2c0_lo and g_mss_i2c1_lo, associated with MSS
1447     I2C 0 and MSS I2C 1 when they are connected on the AXI switch slave 5 (main
1448     APB bus) and g_mss_i2c0_hi and g_mss_i2c1_hi, associated with MSS I2C 0 to
1449     MSS I2C 1 when they are connected on the AXI switch slave 6 (AMP APB bus).
1450     This parameter must point to one of these four global data structure defined
1451     within I2C driver.
1452 
1453   @return none.
1454 
1455   Example:
1456   @code
1457     // Enable I2C slave.
1458     MSS_I2C_enable_slave( &g_mss_i2c0_lo );
1459   @endcode
1460  */
1461 void MSS_I2C_enable_slave
1462 (
1463     mss_i2c_instance_t * this_i2c
1464 );
1465 
1466 /*-------------------------------------------------------------------------*//**
1467   I2C slave disable.
1468   ------------------------------------------------------------------------------
1469   This function disables slave mode operation for an MSS I2C peripheral. It
1470   stops the MSS I2C slave acknowledging I2C read, write or write-read
1471   transactions targeted at it.
1472   ------------------------------------------------------------------------------
1473   @param this_i2c:
1474     The this_i2c parameter is a pointer to an mss_i2c_instance_t structure
1475     identifying the MSS I2C hardware block to be initialized. There are four
1476     such data structures, g_mss_i2c0_lo and g_mss_i2c1_lo, associated with MSS
1477     I2C 0 and MSS I2C 1 when they are connected on the AXI switch slave 5 (main
1478     APB bus) and g_mss_i2c0_hi and g_mss_i2c1_hi, associated with MSS I2C 0 to
1479     MSS I2C 1 when they are connected on the AXI switch slave 6 (AMP APB bus).
1480     This parameter must point to one of these four global data structure defined
1481     within I2C driver.
1482 
1483   @return
1484     This function does not return a value.
1485 
1486   Example:
1487   @code
1488     // Disable I2C slave.
1489     MSS_I2C_disable_slave( &g_mss_i2c0_lo );
1490   @endcode
1491  */
1492 void MSS_I2C_disable_slave
1493 (
1494     mss_i2c_instance_t * this_i2c
1495 );
1496 
1497 /*-------------------------------------------------------------------------*//**
1498   The MSS_I2C_set_gca() function is used to set the general call acknowledgment
1499   bit of an MSS I2C slave device. This allows the slave device respond to a
1500   general call or broadcast message from an I2C master.
1501   ------------------------------------------------------------------------------
1502   @param this_i2c:
1503     The this_i2c parameter is a pointer to an mss_i2c_instance_t structure
1504     identifying the MSS I2C hardware block to be initialized. There are four
1505     such data structures, g_mss_i2c0_lo and g_mss_i2c1_lo, associated with MSS
1506     I2C 0 and MSS I2C 1 when they are connected on the AXI switch slave 5 (main
1507     APB bus) and g_mss_i2c0_hi and g_mss_i2c1_hi, associated with MSS I2C 0 to
1508     MSS I2C 1 when they are connected on the AXI switch slave 6 (AMP APB bus).
1509     This parameter must point to one of these four global data structure defined
1510     within I2C driver.
1511 
1512   @return
1513     This function does not return a value.
1514 
1515   Example:
1516   @code
1517     // Enable recognition of the General Call Address
1518     MSS_I2C_set_gca( &g_mss_i2c0_lo );
1519   @endcode
1520  */
1521 void MSS_I2C_set_gca
1522 (
1523     mss_i2c_instance_t * this_i2c
1524 );
1525 
1526 /*-------------------------------------------------------------------------*//**
1527   The MSS_I2C_clear_gca() function is used to clear the general call
1528   acknowledgment bit of an MSS I2C slave device. This will stop the I2C slave
1529   device responding to any general call or broadcast message from the master.
1530   ------------------------------------------------------------------------------
1531   @param this_i2c:
1532     The this_i2c parameter is a pointer to an mss_i2c_instance_t structure
1533     identifying the MSS I2C hardware block to be initialized. There are four
1534     such data structures, g_mss_i2c0_lo and g_mss_i2c1_lo, associated with MSS
1535     I2C 0 and MSS I2C 1 when they are connected on the AXI switch slave 5 (main
1536     APB bus) and g_mss_i2c0_hi and g_mss_i2c1_hi, associated with MSS I2C 0 to
1537     MSS I2C 1 when they are connected on the AXI switch slave 6 (AMP APB bus).
1538     This parameter must point to one of these four global data structure defined
1539     within I2C driver.
1540 
1541   @return
1542     This function does not return a value.
1543 
1544   Example:
1545   @code
1546     // Disable recognition of the General Call Address
1547     MSS_I2C_clear_gca( &g_mss_i2c0_lo );
1548   @endcode
1549  */
1550 void MSS_I2C_clear_gca
1551 (
1552     mss_i2c_instance_t * this_i2c
1553 );
1554 
1555 /*------------------------------------------------------------------------------
1556                       I2C SMBUS specific APIs
1557  ----------------------------------------------------------------------------*/
1558 
1559 /*-------------------------------------------------------------------------*//**
1560   The MSS_I2C_smbus_init() function enables SMBus timeouts and status logic. Set
1561   the frequency parameter to the MSS I2C�s PCLK frequency for 25ms SMBus
1562   timeouts, or to any frequency between 1 MHz and 255 MHz for to adjust the
1563   timeout.
1564   ------------------------------------------------------------------------------
1565   @param this_i2c:
1566     The this_i2c parameter is a pointer to an mss_i2c_instance_t structure
1567     identifying the MSS I2C hardware block to be initialized. There are four
1568     such data structures, g_mss_i2c0_lo and g_mss_i2c1_lo, associated with MSS
1569     I2C 0 and MSS I2C 1 when they are connected on the AXI switch slave 5 (main
1570     APB bus) and g_mss_i2c0_hi and g_mss_i2c1_hi, associated with MSS I2C 0 to
1571     MSS I2C 1 when they are connected on the AXI switch slave 6 (AMP APB bus).
1572     This parameter must point to one of these four global data structure defined
1573     within I2C driver.
1574 
1575   @param frequency
1576     The frequency parameter specifies a frequency in MHz from 1 to 255. It can
1577     be the MSS I2C�s PCLK frequency to specify 25ms SMBus timeouts, or a higher
1578     or lower frequency than the PCLK for increased or decreased timeouts.
1579 
1580   @return
1581     This function does not return a value.
1582 
1583   Example:
1584   @code
1585     #define SLAVE_SER_ADDR  0x10u
1586 
1587     void system_init( void )
1588     {
1589         MSS_I2C_init( &g_mss_i2c0_lo, SLAVE_SER_ADDR, MSS_I2C_PCLK_DIV_256 );
1590         // Initialize SMBus feature
1591         MSS_I2C_smbus_init( &g_mss_i2c0_lo, 100 );
1592     }
1593   @endcode
1594  */
1595 void MSS_I2C_smbus_init
1596 (
1597     mss_i2c_instance_t * this_i2c,
1598     uint8_t frequency
1599 );
1600 
1601 /*-------------------------------------------------------------------------*//**
1602   The MSS_I2C_enable_smbus_irq() function is used to enable the MSS I2C�s SMBSUS
1603   and SMBALERT SMBus interrupts.
1604 
1605   If this function is used to enable an MSS I2C SMBus interrupt source, the
1606   appropriate interrupt handler must be implemented in the application to
1607   override the weak stub function implemented in the CMSIS-HAL startup code:
1608     - MSS I2C 0 SMBALERT - I2C0_SMBAlert_IRQHandler( ).
1609     - MSS I2C 0 SMBSUS - I2C0_SMBust_IRQHandler( ).
1610     - MSS I2C 1 SMBALERT - I2C1_SMBAlert_IRQHandler( ).
1611     - MSS I2C 1 SMBSUS - I2C1_SMBus_IRQHandler( ).
1612   ------------------------------------------------------------------------------
1613   @param this_i2c:
1614     The this_i2c parameter is a pointer to an mss_i2c_instance_t structure
1615     identifying the MSS I2C hardware block to be initialized. There are four
1616     such data structures, g_mss_i2c0_lo and g_mss_i2c1_lo, associated with MSS
1617     I2C 0 and MSS I2C 1 when they are connected on the AXI switch slave 5 (main
1618     APB bus) and g_mss_i2c0_hi and g_mss_i2c1_hi, associated with MSS I2C 0 to
1619     MSS I2C 1 when they are connected on the AXI switch slave 6 (AMP APB bus).
1620     This parameter must point to one of these four global data structure defined
1621     within I2C driver.
1622 
1623   @param irq_type
1624     The irq_type parameter specifies which SMBus interrupt(s) to enable. The two
1625     possible interrupts are:
1626       MSS_I2C_SMBALERT_IRQ
1627       MSS_I2C_SMBSUS_IRQ
1628     To enable both ints in one call, use MSS_I2C_SMBALERT_IRQ |
1629     MSS_I2C_SMBSUS_IRQ.
1630 
1631   @return
1632     This function does not return a value.
1633 
1634   Example:
1635   @code
1636     #define SLAVE_SER_ADDR     0x10u
1637     void I2C0_SMBAlert_IRQHandler( void )
1638     {
1639         // MSS I2C 0 application specific SMBALERT code goes here ...
1640     }
1641 
1642     void I2C0_SMBus_IRQHandler( void )
1643     {
1644         // MSS I2C 0 application specific SMBus code goes here ...
1645     }
1646 
1647     void main( void )
1648     {
1649         MSS_I2C_init( &g_mss_i2c0_lo, SLAVE_SER_ADDR, MSS_I2C_PCLK_DIV_256 );
1650 
1651         // Initialize SMBus feature
1652         MSS_I2C_smbus_init( &g_mss_i2c0_lo, 100 );
1653 
1654         // Enable both SMBALERT & SMBSUS interrupts
1655         MSS_I2C_enable_smbus_irq( &g_mss_i2c0_lo,
1656                           (uint8_t)(MSS_I2C_SMBALERT_IRQ | MSS_I2C_SMBSUS_IRQ));
1657    }
1658    @endcode
1659  */
1660 void MSS_I2C_enable_smbus_irq
1661 (
1662     mss_i2c_instance_t * this_i2c,
1663     uint8_t  irq_type
1664 );
1665 
1666 /*-------------------------------------------------------------------------*//**
1667   The MSS_I2C_disable_smbus_irq() function is used to disable the MSS I2C's
1668   SMBSUS and SMBALERT SMBus interrupts.
1669   ------------------------------------------------------------------------------
1670   @param this_i2c:
1671     The this_i2c parameter is a pointer to an mss_i2c_instance_t structure
1672     identifying the MSS I2C hardware block to be initialized. There are four
1673     such data structures, g_mss_i2c0_lo and g_mss_i2c1_lo, associated with MSS
1674     I2C 0 and MSS I2C 1 when they are connected on the AXI switch slave 5 (main
1675     APB bus) and g_mss_i2c0_hi and g_mss_i2c1_hi, associated with MSS I2C 0 to
1676     MSS I2C 1 when they are connected on the AXI switch slave 6 (AMP APB bus).
1677     This parameter must point to one of these four global data structure defined
1678     within I2C driver.
1679 
1680   @param irq_type
1681     The irq_type parameter specifies the SMBUS interrupt to be disabled.
1682     The two possible interrupts are:
1683       MSS_I2C_SMBALERT_IRQ
1684       MSS_I2C_SMBSUS_IRQ
1685     To disable both interrupts in one call, use MSS_I2C_SMBALERT_IRQ |
1686     MSS_I2C_SMBSUS_IRQ.
1687 
1688   @return
1689     This function does not return a value.
1690 
1691   Example:
1692   @code
1693     #define SLAVE_SER_ADDR     0x10u
1694     void I2C0_SMBAlert_IRQHandler( void )
1695     {
1696         // MSS I2C 0 application specific SMBALERT code goes here ...
1697     }
1698 
1699     void I2C0_SMBus_IRQHandler( void )
1700     {
1701         // MSS I2C 0 application specific SMBus code goes here ...
1702     }
1703 
1704     void main( void )
1705     {
1706         MSS_I2C_init( &g_mss_i2c0_lo, SLAVE_SER_ADDR, MSS_I2C_PCLK_DIV_256 );
1707 
1708         // Initialize SMBus feature
1709         MSS_I2C_smbus_init( &g_mss_i2c0_lo, 100 );
1710 
1711         // Enable both SMBALERT & SMBSUS interrupts
1712         MSS_I2C_enable_smbus_irq( &g_mss_i2c0_lo,
1713                           (uint8_t)(MSS_I2C_SMBALERT_IRQ | MSS_I2C_SMBSUS_IRQ));
1714 
1715         ...
1716 
1717         // Disable the SMBALERT interrupt
1718         MSS_I2C_disable_smbus_irq( &g_mss_i2c0_lo, MSS_I2C_SMBALERT_IRQ );
1719     }
1720   @endcode
1721  */
1722 void MSS_I2C_disable_smbus_irq
1723 (
1724     mss_i2c_instance_t * this_i2c,
1725     uint8_t  irq_type
1726 );
1727 
1728 /*-------------------------------------------------------------------------*//**
1729   The MSS_I2C_suspend_smbus_slave() function forces any SMBUS slave devices
1730   connected to an MSS I2C peripheral into power down or suspend mode by
1731   asserting the MSS I2C�s I2C_X_SMBSUS_NO output signal. The MSS I2C is the
1732   SMBus master in this case.
1733   ------------------------------------------------------------------------------
1734   @param this_i2c:
1735     The this_i2c parameter is a pointer to an mss_i2c_instance_t structure
1736     identifying the MSS I2C hardware block to be initialized. There are four
1737     such data structures, g_mss_i2c0_lo and g_mss_i2c1_lo, associated with MSS
1738     I2C 0 and MSS I2C 1 when they are connected on the AXI switch slave 5 (main
1739     APB bus) and g_mss_i2c0_hi and g_mss_i2c1_hi, associated with MSS I2C 0 to
1740     MSS I2C 1 when they are connected on the AXI switch slave 6 (AMP APB bus).
1741     This parameter must point to one of these four global data structure defined
1742     within I2C driver.
1743 
1744   @return
1745     This function does not return a value.
1746 
1747   Example:
1748   @code
1749     #define SLAVE_SER_ADDR     0x10u
1750 
1751     void main( void )
1752     {
1753         MSS_I2C_init( &g_mss_i2c0_lo, SLAVE_SER_ADDR, MSS_I2C_PCLK_DIV_256 );
1754 
1755         // Initialize SMBus feature
1756         MSS_I2C_smbus_init( &g_mss_i2c0_lo, 100 );
1757 
1758         // suspend SMBus slaves
1759         MSS_I2C_suspend_smbus_slave( &g_mss_i2c0_lo );
1760 
1761         ...
1762 
1763         // Re-enable SMBus slaves
1764         MSS_I2C_resume_smbus_slave( &g_mss_i2c0_lo );
1765     }
1766   @endcode
1767  */
1768 void MSS_I2C_suspend_smbus_slave
1769 (
1770     mss_i2c_instance_t * this_i2c
1771 );
1772 
1773 /*-------------------------------------------------------------------------*//**
1774   The MSS_I2C_resume_smbus_slave() function de-asserts the MSS I2C's
1775   I2C_X_SMBSUS_NO output signal to take any connected slave devices out of
1776   suspend mode. The MSS I2C is the SMBus master in this case.
1777   ------------------------------------------------------------------------------
1778   @param this_i2c:
1779     The this_i2c parameter is a pointer to an mss_i2c_instance_t structure
1780     identifying the MSS I2C hardware block to be initialized. There are four
1781     such data structures, g_mss_i2c0_lo and g_mss_i2c1_lo, associated with MSS
1782     I2C 0 and MSS I2C 1 when they are connected on the AXI switch slave 5 (main
1783     APB bus) and g_mss_i2c0_hi and g_mss_i2c1_hi, associated with MSS I2C 0 to
1784     MSS I2C 1 when they are connected on the AXI switch slave 6 (AMP APB bus).
1785     This parameter must point to one of these four global data structure defined
1786     within I2C driver.
1787 
1788   @return
1789     This function does not return a value.
1790 
1791   Example:
1792   @code
1793     #define SLAVE_SER_ADDR     0x10u
1794 
1795     void main( void )
1796     {
1797         MSS_I2C_init( &g_mss_i2c0_lo, SLAVE_SER_ADDR, MSS_I2C_PCLK_DIV_256 );
1798 
1799         // Initialize SMBus feature
1800         MSS_I2C_smbus_init( &g_mss_i2c0_lo, 100 );
1801 
1802         // suspend SMBus slaves
1803         MSS_I2C_suspend_smbus_slave( &g_mss_i2c0_lo );
1804 
1805         ...
1806 
1807         // Re-enable SMBus slaves
1808         MSS_I2C_resume_smbus_slave( &g_mss_i2c0_lo );
1809     }
1810   @endcode
1811  */
1812 void MSS_I2C_resume_smbus_slave
1813 (
1814     mss_i2c_instance_t * this_i2c
1815 );
1816 
1817 /*-------------------------------------------------------------------------*//**
1818   The MSS_I2C_reset_smbus() function resets the MSS I2C's SMBus connection by
1819   forcing SCLK low for 35mS. The reset is automatically cleared after 35ms have
1820   elapsed. The MSS I2C is the SMBus master in this case.
1821   ------------------------------------------------------------------------------
1822   @param this_i2c:
1823     The this_i2c parameter is a pointer to an mss_i2c_instance_t structure
1824     identifying the MSS I2C hardware block to be initialized. There are four
1825     such data structures, g_mss_i2c0_lo and g_mss_i2c1_lo, associated with MSS
1826     I2C 0 and MSS I2C 1 when they are connected on the AXI switch slave 5 (main
1827     APB bus) and g_mss_i2c0_hi and g_mss_i2c1_hi, associated with MSS I2C 0 to
1828     MSS I2C 1 when they are connected on the AXI switch slave 6 (AMP APB bus).
1829     This parameter must point to one of these four global data structure defined
1830     within I2C driver.
1831 
1832   @return
1833     This function does not return a value.
1834 
1835   Example:
1836   @code
1837     #define SLAVE_SER_ADDR     0x10u
1838 
1839     void main( void )
1840     {
1841         MSS_I2C_init( &g_mss_i2c0_lo, SLAVE_SER_ADDR, MSS_I2C_PCLK_DIV_256 );
1842 
1843         // Initialize SMBus feature
1844         MSS_I2C_smbus_init( &g_mss_i2c0_lo, 100 );
1845 
1846         // Make sure the SMBus channel is in a known state by resetting it
1847         MSS_I2C_reset_smbus( &g_mss_i2c0_lo );
1848     }
1849   @endcode
1850  */
1851 void MSS_I2C_reset_smbus
1852 (
1853     mss_i2c_instance_t * this_i2c
1854 );
1855 
1856 /*-------------------------------------------------------------------------*//**
1857   The MSS_I2C_set_smbus_alert() function is used to force master communication
1858   with an I2C slave device by asserting the MSS I2C's I2C_X_SMBALERT_NO signal.
1859   The MSS I2C is the SMBus master in this case.
1860   ------------------------------------------------------------------------------
1861   @param this_i2c:
1862     The this_i2c parameter is a pointer to an mss_i2c_instance_t structure
1863     identifying the MSS I2C hardware block to be initialized. There are four
1864     such data structures, g_mss_i2c0_lo and g_mss_i2c1_lo, associated with MSS
1865     I2C 0 and MSS I2C 1 when they are connected on the AXI switch slave 5 (main
1866     APB bus) and g_mss_i2c0_hi and g_mss_i2c1_hi, associated with MSS I2C 0 to
1867     MSS I2C 1 when they are connected on the AXI switch slave 6 (AMP APB bus).
1868     This parameter must point to one of these four global data structure defined
1869     within I2C driver.
1870 
1871   @return
1872     This function does not return a value.
1873 
1874   Example:
1875   @code
1876     #define SLAVE_SER_ADDR     0x10u
1877 
1878     void main( void )
1879     {
1880         MSS_I2C_init( &g_mss_i2c0_lo, SLAVE_SER_ADDR, MSS_I2C_PCLK_DIV_256 );
1881 
1882         // Initialize SMBus feature
1883         MSS_I2C_smbus_init( &g_mss_i2c0_lo, 100 );
1884 
1885         // Get the SMBus masters attention
1886         MSS_I2C_set_smbus_alert( &g_mss_i2c0_lo );
1887 
1888         ...
1889 
1890         // Once we are happy, drop the alert
1891         MSS_I2C_clear_smbus_alert( &g_mss_i2c0_lo );
1892     }
1893   @endcode
1894  */
1895 void MSS_I2C_set_smbus_alert
1896 (
1897     mss_i2c_instance_t * this_i2c
1898 );
1899 
1900 /*-------------------------------------------------------------------------*//**
1901   The MSS_I2C_clear_smbus_alert() function is used de-assert the MSS I2C�s
1902   I2C_X_SMBALERT_NO signal once a slave device has had a response from the
1903   master. The MSS I2C is the SMBus slave in this case.
1904   ------------------------------------------------------------------------------
1905   @param this_i2c:
1906     The this_i2c parameter is a pointer to an mss_i2c_instance_t structure
1907     identifying the MSS I2C hardware block to be initialized. There are four
1908     such data structures, g_mss_i2c0_lo and g_mss_i2c1_lo, associated with MSS
1909     I2C 0 and MSS I2C 1 when they are connected on the AXI switch slave 5 (main
1910     APB bus) and g_mss_i2c0_hi and g_mss_i2c1_hi, associated with MSS I2C 0 to
1911     MSS I2C 1 when they are connected on the AXI switch slave 6 (AMP APB bus).
1912     This parameter must point to one of these four global data structure defined
1913     within I2C driver.
1914 
1915   @return
1916     This function does not return a value.
1917 
1918   Example:
1919   @code
1920     #define SLAVE_SER_ADDR     0x10u
1921 
1922     void main( void )
1923     {
1924         MSS_I2C_init( &g_mss_i2c0_lo, SLAVE_SER_ADDR, MSS_I2C_PCLK_DIV_256 );
1925 
1926         // Initialize SMBus feature
1927         MSS_I2C_smbus_init( &g_mss_i2c0_lo, 100 );
1928 
1929         // Get the SMBus masters attention
1930         MSS_I2C_set_smbus_alert( &g_mss_i2c0_lo );
1931 
1932         ...
1933 
1934         // Once we are happy, drop the alert
1935         MSS_I2C_clear_smbus_alert( &g_mss_i2c0_lo );
1936     }
1937   @endcode
1938  */
1939 void MSS_I2C_clear_smbus_alert
1940 (
1941     mss_i2c_instance_t * this_i2c
1942 );
1943 
1944 /*-------------------------------------------------------------------------*//**
1945   The MSS_I2C_set_user_data() function is used to allow the association of a
1946   block of application specific data with an MDD I2C peripheral. The composition
1947   of the data block is an application matter and the driver simply provides the
1948   means for the application to set and retrieve the pointer. This may for
1949   example be used to provide additional channel specific information to the
1950   slave write handler.
1951   ------------------------------------------------------------------------------
1952   @param this_i2c:
1953     The this_i2c parameter is a pointer to an mss_i2c_instance_t structure
1954     identifying the MSS I2C hardware block to be initialized. There are four
1955     such data structures, g_mss_i2c0_lo and g_mss_i2c1_lo, associated with MSS
1956     I2C 0 and MSS I2C 1 when they are connected on the AXI switch slave 5 (main
1957     APB bus) and g_mss_i2c0_hi and g_mss_i2c1_hi, associated with MSS I2C 0 to
1958     MSS I2C 1 when they are connected on the AXI switch slave 6 (AMP APB bus).
1959     This parameter must point to one of these four global data structure defined
1960     within I2C driver.
1961 
1962   @param p_user_data
1963     The p_user_data parameter is a pointer to the user specific data block for
1964     this MSS I2C peripheral. It is defined as void * as the driver does not
1965     know the actual type of data being pointed to and simply stores the pointer
1966     for later retrieval by the application.
1967 
1968   @return
1969     This function does not return a value.
1970 
1971   Example
1972   @code
1973     #define SLAVE_SER_ADDR     0x10u
1974 
1975     app_data_t channel_xdata;
1976 
1977     void main( void )
1978     {
1979         app_data_t *p_xdata;
1980 
1981         MSS_I2C_init( &g_mss_i2c0_lo, SLAVE_SER_ADDR, MSS_I2C_PCLK_DIV_256 );
1982 
1983         // Store location of user data in instance structure
1984         MSS_I2C_set_user_data( &g_mss_i2c0_lo, (void *)&channel_xdata );
1985 
1986         ...
1987 
1988         // Retrieve location of user data and do some work on it
1989         p_xdata = (app_data_t *)MSS_I2C_get_user_data( &g_mss_i2c0_lo );
1990         if( NULL != p_xdata )
1991         {
1992             p_xdata->foo = 123;
1993         }
1994     }
1995   @endcode
1996  */
1997 void MSS_I2C_set_user_data
1998 (
1999     mss_i2c_instance_t * this_i2c,
2000     void * p_user_data
2001 );
2002 
2003 /*-------------------------------------------------------------------------*//**
2004   The MSS_I2C_get_user_data() function is used to allow the retrieval of the
2005   address of a block of application specific data associated with an MSS I2C
2006   peripheral. The composition of the data block is an application matter and the
2007   driver simply provides the means for the application to set and retrieve the
2008   pointer. This may for example be used to provide additional channel specific
2009   information to the slave write handler.
2010   ------------------------------------------------------------------------------
2011   @param this_i2c:
2012     The this_i2c parameter is a pointer to an mss_i2c_instance_t structure
2013     identifying the MSS I2C hardware block to be initialized. There are four
2014     such data structures, g_mss_i2c0_lo and g_mss_i2c1_lo, associated with MSS
2015     I2C 0 and MSS I2C 1 when they are connected on the AXI switch slave 5 (main
2016     APB bus) and g_mss_i2c0_hi and g_mss_i2c1_hi, associated with MSS I2C 0 to
2017     MSS I2C 1 when they are connected on the AXI switch slave 6 (AMP APB bus).
2018     This parameter must point to one of these four global data structure defined
2019     within I2C driver.
2020 
2021   @return
2022     This function returns a pointer to the user specific data block for this
2023     MSS I2C peripheral. It is defined as void * as the driver does not know the
2024     actual type of data being pointed to. If no user data has been registered
2025     for this channel a NULL pointer is returned.
2026 
2027   Example
2028   @code
2029     #define SLAVE_SER_ADDR     0x10u
2030 
2031     app_data_t channel_xdata;
2032 
2033     void main( void )
2034     {
2035         app_data_t *p_xdata;
2036 
2037         MSS_I2C_init( &g_mss_i2c0_lo, SLAVE_SER_ADDR, MSS_I2C_PCLK_DIV_256 );
2038 
2039         // Store location of user data in instance structure
2040         MSS_I2C_set_user_data( &g_mss_i2c0_lo, (void *)&channel_xdata );
2041 
2042         ...
2043 
2044         // Retrieve location of user data and do some work on it
2045         p_xdata = (app_data_t *)MSS_I2C_get_user_data( &g_mss_i2c0_lo );
2046         if( NULL != p_xdata )
2047         {
2048             p_xdata->foo = 123;
2049         }
2050     }
2051   @endcode
2052  */
2053 void * MSS_I2C_get_user_data
2054 (
2055     mss_i2c_instance_t * this_i2c
2056 );
2057 
2058 /*-------------------------------------------------------------------------*//**
2059   The MSS_I2C_register_transfer_completion_handler() function is used register
2060   transfer completion call back function. This mechanism is used to
2061   notify the completion of the previously initiated I2C transfer when MSS I2C
2062   instance is operating as I2C Master. This call back function will be called
2063   when the transfer is completed. It will also inform the transfer status as a
2064   parameter of the completion handler function.
2065   This function must be called after I2C initialization and before starting any
2066   transmit or receive operations.
2067   ------------------------------------------------------------------------------
2068   @param this_i2c:
2069     The this_i2c parameter is a pointer to an mss_i2c_instance_t structure
2070     identifying the MSS I2C hardware block to be initialized. There are four
2071     such data structures, g_mss_i2c0_lo and g_mss_i2c1_lo, associated with MSS
2072     I2C 0 and MSS I2C 1 when they are connected on the AXI switch slave 5 (main
2073     APB bus) and g_mss_i2c0_hi and g_mss_i2c1_hi, associated with MSS I2C 0 to
2074     MSS I2C 1 when they are connected on the AXI switch slave 6 (AMP APB bus).
2075     This parameter must point to one of these four global data structure defined
2076     within I2C driver.
2077 
2078   @param completion_handler:
2079     The completion_handler parameter pointers to the function that informs to
2080     application previously initiated I2C transfer is completed along with
2081     transfer status.
2082 
2083   @return
2084     This function does not return a value.
2085 
2086   Example
2087   @code
2088     void i2c0_completion_handler(mss_i2c_instance_t * instance,
2089                                  mss_i2c_status_t status)
2090     {
2091         if (status == MSS_I2C_SUCCESS)
2092         {
2093             MSS_UART_polled_tx_string(gp_my_uart, (const uint8_t*)"\rI2C0 \
2094                                       Transfer completed.\n\r");
2095         }
2096     }
2097 
2098     void main()
2099     {
2100         MSS_I2C_init(I2C_MASTER, MASTER_SER_ADDR, MSS_I2C_BCLK_DIV_8);
2101         MSS_I2C_register_transfer_completion_handler(I2C_MASTER,
2102                                                      i2c0_completion_handler);
2103     }
2104   @endcode
2105  */
2106 void MSS_I2C_register_transfer_completion_handler
2107 (
2108     mss_i2c_instance_t * this_i2c,
2109     mss_i2c_transfer_completion_t completion_handler
2110 );
2111 
2112 #ifdef __cplusplus
2113 }
2114 #endif
2115 
2116 #endif /*MSS_I2C_H_*/
2117