2.3 I2C Host Driver
2.3.1 Introduction
The MPLAB® Code Configurator (MCC) Melody Inter-Integrated Circuit (I2C) Host Driver generates a portable API to support a generic I2C host interface, and also two important MCC Melody Component concepts: configuration- and firmware-portability.
The I2C Host Driver requires a Peripheral Library (PLIB) dependency that is closely associated to an I2C hardware peripheral. On PIC® MCUs, this typically takes the form of a either an I2C or a MSSP (Master Synchronous Serial Port) hardware peripheral.
The I2C bus is a multi-host serial data communication busDevices communicate in a host/client environment where the host devices initiate the communication. A client device is controlled through addressing.
2.3.2 Required Header Files
#include <stdbool.h> #include <stdint.h> #include "mcc_generated_files/i2c_host/i2c_host_interface.h"
2.3.3 How to Use the I2C Host Driver
The I2C Host Driver can be used in polled or interrupt modes. Click the links to view the code snippets associated with each:
I2C Host Driver Use-Case examples:
- I2C Host Polling Use-Case 1: In this I2C Host Polling example, a byte of data is written in to Client and read it back. Case 1: Data 0xAA is written in to Client at location 0x0010 and read the same back, using I2C1_Host.Write() and I2C1_Host.WriteRead() functions.
- I2C Host Polling Use-Case 2: In this I2C Host Polling example, a byte of data is written in to Client and read it back. Case 2: Data 0x55 is written in to Client at location 0x0020 and read the same back using I2C1_Host.Write() and I2C1_Host.Read() functions.
- I2C Host Interrupt Use-Case 1: In this I2C Host interrupt example, a byte of data is written in to Client and read it back. Case 1: Data 0xAA is written in to Client at location 0x0010 and read the same back, using I2C1_Host.Write() and I2C1_Host.WriteRead() functions.
- I2C Host Interrupt Use-Case 2: In this I2C Host interrupt example, a byte of data is written in to Client and read it back. Case 2: Data 0x55 is written in to Client at location 0x0020 and read the same back using I2C1_Host.Write() and I2C1_Host.Read() functions.
2.3.4 I2C Host Driver Documentation
2.3.4.1 Module Documentation
2.3.4.1.1 I2C_HOST_DRIVER
Module description
Modules
-
This file contains other data types for I2C module.
-
This file contains other data types for I2C module.
I2C_HOST_INTERFACE
This file contains other data types for I2C module.
Module description
This file contains other data types for I2C module.
Data structures
-
struct i2c_host_interface_t
Structure containing the function pointers of I2C drivers.
I2C_HOST_EVENTS
This file contains other data types for I2C module.
Module description
This file contains other data types for I2C module.
Data structures
-
struct i2c_host_event_status_t
I2C Event Status Structure.
2.3.4.1.2 I2C_host_example
I2C Host Basics
The Inter-Integrated Circuit (I2C) bus is a multi-host serial data communication bus. The devices communicate in a host/client environment where the host devices initiate the communication. A client receives commands/input/data through addressing.
Host Examples Include files
Host Polling Example Case 1
Host Polling Example Case 2
Host Interrupt Example Case 1
Host Interrupt Example Case 2
I2C Host Examples
The examples below illustrate how to use the microcontroller as a I2C device in Host mode. The Polling mode and the Interrupt mode are shown in two separate cases, in which the host device writes a value and the client device reads it back. The client device used in this example has 16-bit registers, therefore both Most Significant Byte (MSB) and Least Significant Byte (LSB) are being transmitted.
All the host examples use include these files:
#include "mcc_generated_files/system/system.h" #include "mcc_generated_files/i2c_host/i2c1.h" #include "mcc_generated_files/i2c_host/i2c_host_interface.h"
I2C Host Polling Example Case 1
Data 0xAA is written to the client at location 0x0010 and read back, using the I2C1_Host.Write( ) and I2C1_Host.WriteRead( ) functions.
void I2C_host_example_polling_case_1(void) { uint8_t clientAddr = 0x50; // 7-bit Client address uint8_t deviceRegAddrMsb = 0x00; // MSB of Client location address uint8_t deviceRegAddrLsb = 0x10; // LSB of Client location address // Desired write and read lengths uint8_t writeLength; uint8_t readLength; // Write and read data buffers (buffersize is set for some overhead) uint8_t transmitData[10] = {}; uint8_t readData[10] = {}; uint8_t waitCounter = 0; // Initializes Clock, Pins, Interrupts and I2C Initialize SYSTEM_Initialize(); // Write to client device transmitData[0] = deviceRegAddrMsb; // load MSB of Client location address transmitData[1] = deviceRegAddrLsb; // load LSB of Client location address transmitData[2] = 0xAA; // load data writeLength = 3; // 2 bytes of location address + 1 byte data if ( I2C1_Host.Write(clientAddr, transmitData, writeLength)) { waitCounter = 100; // This value depends on the system clock, I2C clock and data length. while ( I2C1_Host.IsBusy()) { I2C1_Host.Tasks(); waitCounter--; } if ( I2C1_Host.ErrorGet() == I2C_ERROR_NONE) { // Write operation is successful } else { // Error handling } } // Read from client device writeLength = 2; // 2 bytes of location address readLength = 1; // 1 byte read if (I2C1_Host.WriteRead(clientAddr, transmitData, writeLength, readData , readLength)) { waitCounter = 100; // This value depends on the system clock, I2C clock and data length. while ( I2C1_Host.IsBusy()) { I2C1_Host.Tasks(); waitCounter--; } if ( I2C1_Host.ErrorGet() == I2C_ERROR_NONE) { // WriteRead operation is successful } else { // Error handling } } }
I2C Host Polling Example Case 2
Data 0x55 is written to the client at location 0x0020 and read back using the I2C1_Host.Write( ) and I2C1_Host.Read( ) functions.
void I2C_host_example_polling_case_2(void) { uint8_t clientAddr = 0x50; // 7-bit Client address uint8_t deviceRegAddrMsb = 0x00; // MSB of Client location address uint8_t deviceRegAddrLsb = 0x20; // LSB of Client location address // Desired write and read lengths uint8_t writeLength; uint8_t readLength; // Write and read data buffers (buffersize is set for some overhead) uint8_t transmitData[10] = {}; uint8_t readData[10] = {}; uint8_t waitCounter = 0; // Initializes Clock, Pins, Interrupts and I2C Initialize SYSTEM_Initialize(); // Write to client device transmitData[0] = 0x00; // load MSB of Client location address transmitData[1] = 0x20; // load LSB of Client location address transmitData[2] = 0x55; // load data writeLength = 3; // 2 bytes of location address + 1 byte data if (I2C1_Host.Write(clientAddr, transmitData, writeLength)) { waitCounter = 100; // This value depends on the system clock, I2C clock and data length. while (I2C1_Host.IsBusy()) { I2C1_Host.Tasks(); waitCounter--; } if ( I2C1_Host.ErrorGet() == I2C_ERROR_NONE) { // Write operation is successful } else { // Error handling } } // Write which register we wish to read from writeLength = 2; // 2 bytes of location address if (I2C1_Host.Write(clientAddr, transmitData, writeLength)) { waitCounter = 100; // This value depends on the system clock, I2C clock and data length. while (I2C1_Host.IsBusy()) { I2C1_Host.Tasks(); waitCounter--; } if ( I2C1_Host.ErrorGet() == I2C_ERROR_NONE) { // Write operation is successful } else { // Error handling } } // Read from client device readLength = 1; // 1 byte read if (I2C1_Host.Read(clientAddr, readData, readLength)) { waitCounter = 100; // This value depends on the system clock, I2C clock and data length. while (I2C1_Host.IsBusy()) { I2C1_Host.Tasks(); waitCounter--; } if ( I2C1_Host.ErrorGet() == I2C_ERROR_NONE) { // Read operation is successful } else { // Error handling } } }
I2C Host Interrupt Example Case 1
Data 0xAA is written to the client at location 0x0010 and read back using the I2C1_Host.Write( ) and I2C1_Host.WriteRead( ) functions.
void I2C_host_example_interrupt_case_1(void) { uint8_t clientAddr = 0x50; // 7-bit Client address uint8_t deviceRegAddrMsb = 0x00; // MSB of Client location address uint8_t deviceRegAddrLsb = 0x10; // LSB of Client location address // Desired write and read lengths uint8_t writeLength; uint8_t readLength; // Write and read data buffers (buffersize is set for some overhead) uint8_t transmitData[10] = {}; uint8_t readData[10] = {}; // Initializes Clock, Pins, Interrupts and I2C Interface SYSTEM_Initialize(); INTERRUPT_GlobalInterruptEnable(); // Write to client device transmitData[0] = deviceRegAddrMsb; // load MSB of Client location address transmitData[1] = deviceRegAddrLsb; // load LSB of Client location address transmitData[2] = 0xAA; // load data writeLength = 3; // 2 bytes of location address + 1 byte data if(!I2C1_Host.Write(clientAddr, transmitData, writeLength)) { // I2C bus busy, retry later } // Confirm write operation completed and check for error if(!I2C1_Host.IsBusy()) { if ( I2C1_Host.ErrorGet() == I2C_ERROR_NONE) { // Write operation is successful } else { // Error handling } } // Read from client device writeLength = 2; // 2 bytes of location address readLength = 1; // 1 byte read if(I2C1_Host.WriteRead(clientAddr, transmitData, writeLength, readData , readLength)) { // I2C bus busy, retry later } // Confirm write operation completed and check for error if(!I2C1_Host.IsBusy()) { if ( I2C1_Host.ErrorGet() == I2C_ERROR_NONE) { // WriteRead operation is successful } else { // Error handling } } }
I2C Host Interrupt Example Case 2
Data 0x55 is written to the client at location 0x0020 and read back using the I2C1_Host.Write( ) and I2C1_Host.Read( ) functions.
void I2C_host_example_interrupt_case_2(void) { uint8_t clientAddr = 0x50; // 7-bit Client address uint8_t deviceRegAddrMsb = 0x00; // MSB of Client location address uint8_t deviceRegAddrLsb = 0x20; // LSB of Client location address // Desired write and read lengths uint8_t writeLength; uint8_t readLength; // Write and read data buffers (buffersize is set for some overhead) uint8_t transmitData[10] = {}; uint8_t readData[10] = {}; // Initializes Clock, Pins, Interrupts and I2C Interface SYSTEM_Initialize(); INTERRUPT_GlobalInterruptEnable(); // Write to client device transmitData[0] = deviceRegAddrMsb; // load MSB of Client location address transmitData[1] = deviceRegAddrLsb; // load LSB of Client location address transmitData[2] = 0x55; // load data writeLength = 2 + 1; // 2 bytes of location address + 1 byte data if(!I2C1_Host.Write(clientAddr, transmitData, writeLength)) { // I2C bus busy, retry later } // Confirm write operation completed and check for error if(!I2C1_Host.IsBusy()) { if ( I2C1_Host.ErrorGet() == I2C_ERROR_NONE) { // Write operation is successful } else { // Error handling } } // Write which register we wish to read from writeLength = 2; // 2 bytes of location address if(!I2C1_Host.Write(clientAddr, transmitData, writeLength)) { // I2C bus busy, retry later } // Confirm write operation completed and check for error if(!I2C1_Host.IsBusy()) { if ( I2C1_Host.ErrorGet() == I2C_ERROR_NONE) { // Write operation is successful } else { // Error handling } } // Read from client device readLength = 1; // 1 byte read if(!I2C1_Host.Read(clientAddr, readData, readLength))) { // I2C bus busy, retry later } // Confirm write operation completed and check for error if(!I2C1_Host.IsBusy()) { if ( I2C1_Host.ErrorGet() == I2C_ERROR_NONE) { // Read operation is successful } else { // Error handling } } }
2.3.4.2 Class Documentation
2.3.4.2.1 i2c_host_event_status_t Struct Reference
I2C Event Status Structure.
Detailed Description
I2C Event Status Structure.
#include <i2c_host_event_types.h>
Public Attributes
-
bool busy
-
uint16_t address
-
uint8_t * writePtr
-
size_t writeLength
-
uint8_t * readPtr
-
size_t readLength
-
bool switchToRead
-
i2c_host_error_t errorState
Member Data Documentation
The documentation for this struct was generated from the following file:
source/
address
uint16_t i2c_host_event_status_t::address
Pointer to write buffer
busy
bool i2c_host_event_status_t::busy
Software busy flag
errorState
i2c_host_error_t i2c_host_event_status_t::errorState
Error State
readLength
size_t i2c_host_event_status_t::readLength
Read buffer length
readPtr
uint8_t* i2c_host_event_status_t::readPtr
Pointer to read buffer
switchToRead
bool i2c_host_event_status_t::switchToRead
Switch i2c write to read mode
writeLength
size_t i2c_host_event_status_t::writeLength
Write buffer length
writePtr
uint8_t* i2c_host_event_status_t::writePtr
Pointer to write buffer
2.3.4.2.2 i2c_host_interface_t Struct Reference
Structure containing the function pointers of I2C drivers.
Detailed Description
Structure containing the function pointers of I2C drivers.
Section: Included Files
#include <i2c_host_interface.h>
The documentation for this struct was generated from the following file:
source/
Public Attributes
-
void(* Initialize )(void)
-
void(* Deinitialize )(void)
-
bool(* Write )(uint16_t address, uint8_t *data, size_t dataLength)
-
bool(* Read )(uint16_t address, uint8_t *data, size_t dataLength)
-
bool(* WriteRead )(uint16_t address, uint8_t *writeData, size_t writeLength, uint8_t *readData, size_t readLength)
-
bool(* TransferSetup )(i2c_host_transfer_setup_t *setup, uint32_t srcClkFreq)
-
i2c_host_error_t(* ErrorGet )(void)
-
bool(* IsBusy )(void)
-
void(* CallbackRegister )(void(*callback)(void))
-
void(* Tasks )(void)
2.3.4.3 File Documentation
2.3.4.3.1 source/i2c_host_event_types.h File Reference
#include "i2c_host_types.h"
Data structures
-
struct i2c_host_event_status_t
I2C Event Status Structure.
Detailed Description
I2C Generated Driver Event Header File
2.3.4.3.2 source/i2c_host_interface.h File Reference
#include <stdbool.h> #include <stdint.h> #include <xc.h> #include "i2c_host_types.h"
Data structures
-
struct i2c_host_interface_t
Structure containing the function pointers of I2C drivers.
Detailed Description
I2C Generated Driver Interface Header File