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