2.2 I2C Host Driver
2.2.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 AVR® MCUs, this is typically a Two Wire Interface (TWI) peripheral.
The 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 device receives commands/data through addressing.
2.2.2 Required Header Files:
For Host mode, include the following files in your application to use the I2C abstract driver:
#include <stdbool.h> #include <stdint.h> #include "mcc_generated_files/i2c_host/i2c_host_interface.h"
2.2.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: Data 0xAA is written to the client at location 0x0010 and read back, using the I2C1_Host.Write( ) and I2C1_Host.WriteRead( ) functions.
- I2C Host Polling Use - 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.
- I2C Host Interrupt Use - 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.
- I2C Host Interrupt Use - 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.
2.2.4 Module Documentation
2.2.4.1 TWI_HOST_DRIVER
2.2.4.1.1 Module description
Modules
-
This header file provides APIs for the TWI0 driver.
-
This header file provides APIs for the TWI0 driver.
TWI_HOST_INTERFACE
This header file provides APIs for the TWI0 driver.
Module description
This header file provides APIs for the TWI0 driver.
Data structures
-
struct i2c_host_interface_t
Structure containing the function pointers of I2C driver.
TWI0_HOST_EVENT
This header file provides APIs for the TWI0 driver.
Module description
This header file provides APIs for the TWI0 driver.
Enumerations
-
enum i2c_event_states_t { I2C_STATE_IDLE = 0, I2C_STATE_SEND_RD_ADDR, I2C_STATE_SEND_WR_ADDR, I2C_STATE_TX, I2C_STATE_RX, I2C_STATE_NACK, I2C_STATE_ERROR, I2C_STATE_STOP, I2C_STATE_RESET }
Enumeration for I2C states.
2.2.4.2 I2C_host_example
2.2.4.2.1 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 device 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
2.2.4.2.2 I2C Host Examples
The examples below illustrates 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"
2.2.4.2.3 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 } } }
2.2.4.2.4 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 } } }
2.2.4.2.5 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 } } }
2.2.4.2.6 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.2.5 Class Documentation
2.2.5.1 i2c_event_status_t Struct Reference
The documentation for this struct was generated from the following file:
source/
2.2.5.1.1 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
-
i2c_event_states_t state
2.2.5.2 i2c_host_interface_t Struct Reference
Structure containing the function pointers of I2C driver.
2.2.5.2.1 Detailed Description
Structure containing the function pointers of I2C driver.
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 )(struct I2C_TRANSFER_SETUP *setup, uint32_t srcClkFreq)
-
i2c_host_error_t(* ErrorGet )(void)
-
bool(* IsBusy )(void)
-
void(* CallbackRegister )(void(*callback)(void))
-
void(* Tasks )(void)
2.2.6 File Documentation
2.2.6.1 source/i2c_host_event_types.h File Reference
#include "i2c_host_types.h"
2.2.6.1.1 Data structures
-
struct i2c_event_status_t
2.2.6.1.2 Enumerations
-
enum i2c_event_states_t { I2C_STATE_IDLE = 0, I2C_STATE_SEND_RD_ADDR, I2C_STATE_SEND_WR_ADDR, I2C_STATE_TX, I2C_STATE_RX, I2C_STATE_NACK, I2C_STATE_ERROR, I2C_STATE_STOP, I2C_STATE_RESET }
Enumeration for I2C states.
2.2.6.1.3 Detailed Description
TWI0 Generated Driver API Header File
2.2.6.2 source/i2c_host_interface.h File Reference
#include <stdbool.h> #include <stdint.h> #include <xc.h> #include "i2c_host_types.h"
2.2.6.2.1 Data structures
-
struct i2c_host_interface_t
Structure containing the function pointers of I2C driver.
2.2.6.2.2 Detailed Description
TWI0 Generated Driver API Header File