2.4 I2C Client Driver
2.4.1 Introduction
The MPLAB® Code Configurator (MCC) Melody Inter-Integrated Circuit (I2C) Client 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 Client 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.4.2 Required Header Files
#include <stdbool.h> #include <stdint.h> #include "mcc_generated_files/i2c_client/i2c_client_interface.h"
2.4.3 How to Use the I2C Client Driver
The I2C Client Driver can be used in polled or interrupt modes. Click the links to view the code snippets associated with each:
I2C Client Driver Use-Case examples:
- I2C Client Polling Example: This example assumes that the MCU is configured as a Client and responds to the Host commands to write or read data via the Client_Application switch case that executes the appropriate action based on the events that occur.
- I2C Client Interrupt Example: This example assumes that the MCU is configured as a Client and responds to the Host commands to write or read data via the Client_Application switch case that executes the appropriate action based on the events that occur.
2.4.4 I2C Client Driver Documentation
2.4.4.1 Module Documentation
2.4.4.1.1 I2C_CLIENT_DRIVER
Module description
Modules
-
This file contains other data types for I2C module.
I2C_CLIENT_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_client_interface_t
Structure containing the function pointers of I2C driver.
I2C_CLIENT_TYPES
This file contains other data types for I2C module.
Module description
This file contains other data types for I2C module.
Enumerations
-
enum i2c_client_transfer_dir_t { I2C_CLIENT_TRANSFER_DIR_WRITE = 0, I2C_CLIENT_TRANSFER_DIR_READ = 1 }
I2C_CLIENT_TRANSFER_DIR Enumeration.
-
enum i2c_client_ack_status_t { I2C_CLIENT_ACK_STATUS_RECEIVED_ACK = 0, I2C_CLIENT_ACK_STATUS_RECEIVED_NACK = 1 }
I2C Ack/Nack status enumeration.
-
enum i2c_client_transfer_event_t { I2C_CLIENT_TRANSFER_EVENT_NONE = 0, I2C_CLIENT_TRANSFER_EVENT_ADDR_MATCH, I2C_CLIENT_TRANSFER_EVENT_RX_READY, I2C_CLIENT_TRANSFER_EVENT_TX_READY, I2C_CLIENT_TRANSFER_EVENT_STOP_BIT_RECEIVED, I2C_CLIENT_TRANSFER_EVENT_ERROR }
I2C notification event type.
-
enum i2c_client_error_t { I2C_CLIENT_ERROR_NONE = 0, I2C_CLIENT_ERROR_BUS_COLLISION, I2C_CLIENT_ERROR_WRITE_COLLISION, I2C_CLIENT_ERROR_RECEIVE_OVERFLOW, I2C_CLIENT_ERROR_TRANSMIT_UNDERFLOW, I2C_CLIENT_ERROR_READ_UNDERFLOW }
I2C client error type indicator.
Enumeration Type Documentation
i2c_client_ack_status_t
I2C Ack/Nack status enumeration.
I2C_CLIENT_ACK_STATUS_RECEIVED_ACK |
I2C Host is send ACK to client | |
I2C_CLIENT_ACK_STATUS_RECEIVED_NACK |
I2C Host is send NACK to client |
i2c_client_error_t
enum i2c_client_error_t
I2C client error type indicator.
I2C_CLIENT_ERROR_NONE |
I2C error none | |
I2C_CLIENT_ERROR_BUS_COLLISION |
I2C Bus collision occurred | |
I2C_CLIENT_ERROR_WRITE_COLLISION |
I2C Write collision occurred | |
I2C_CLIENT_ERROR_RECEIVE_OVERFLOW |
I2C Receive overflow occurred | |
I2C_CLIENT_ERROR_TRANSMIT_UNDERFLOW |
I2C Trasmit underflow occurred | |
I2C_CLIENT_ERROR_READ_UNDERFLOW |
I2C Receive underflow occurred |
i2c_client_transfer_dir_t
enum i2c_client_transfer_dir_t
I2C_CLIENT_TRANSFER_DIR Enumeration.
I2C_CLIENT_TRANSFER_DIR_WRITE |
I2C Host is writing to client | |
I2C_CLIENT_TRANSFER_DIR_READ |
I2C Host is reading from client |
i2c_client_transfer_event_t
enum i2c_client_transfer_event_t
I2C notification event type.
I2C_CLIENT_TRANSFER_EVENT_NONE |
I2C Bus Idle state | |
I2C_CLIENT_TRANSFER_EVENT_ADDR_MATCH |
Address match event | |
I2C_CLIENT_TRANSFER_EVENT_RX_READY |
Data sent by I2C Host is available | |
I2C_CLIENT_TRANSFER_EVENT_TX_READY |
I2C client can respond to data read request from I2C Host | |
I2C_CLIENT_TRANSFER_EVENT_STOP_BIT_RECEIVED |
I2C stop bit received | |
I2C_CLIENT_TRANSFER_EVENT_ERROR |
I2C Bus error occurred |
2.4.4.1.2 I2C_client_example
I2C Client 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.
Client Examples Include files
Client Polling Example
Client Interrupt Example
I2C Client Examples
The examples below illustrate how to use the microcontroller as a I2C device in Client mode. Both cases show how to use the callbackRegister and the i2c_client_transfer_events to handle the I2C communication.
All the Client examples will use these includes:
#include "mcc_generated_files/system/system.h" #include "mcc_generated_files/i2c_client/i2c1.h" #include "mcc_generated_files/i2c_client/i2c_client_interface.h"
I2C Client Polling Example
This example assumes that the MCU is configured as a client and responds to the host commands to write or read data via the Client_Application switch case, which selects and implements the appropriate action based on the events that occur.
#define I2C_CLIENT_LOCATION_SIZE 10 //Private functions static bool Client_Application(i2c_client_transfer_event_t event); // Private variable volatile static uint8_t CLIENT_DATA[I2C_CLIENT_LOCATION_SIZE] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09 }; static uint8_t clientLocation = 0x00; static bool isClientLocation = false; int I2C_client_example_polling(void) { SYSTEM_Initialize(); I2C1_Client.CallbackRegister(Client_Application); while (1) { I2C1_Client.Tasks(); } } static bool Client_Application(i2c_client_transfer_event_t event) { switch (event) { case I2C_CLIENT_TRANSFER_EVENT_ADDR_MATCH: //Address Match occured if (I2C1_Client.TransferDirGet() == I2C_CLIENT_TRANSFER_DIR_WRITE) { isClientLocation = true; } break; case I2C_CLIENT_TRANSFER_EVENT_RX_READY: //Read the data sent by I2C Host if (isClientLocation ) { clientLocation = I2C1_Client.ReadByte(); isClientLocation = false; break; } else { CLIENT_DATA[clientLocation ++] = I2C1_Client.ReadByte(); if (clientLocation >= I2C_CLIENT_LOCATION_SIZE) { clientLocation = 0x00; } } break; case I2C_CLIENT_TRANSFER_EVENT_TX_READY: // Provide the Client data requested by the I2C Host I2C1_Client.WriteByte(CLIENT_DATA[clientLocation ++]); if (clientLocation >= I2C_CLIENT_LOCATION_SIZE) { clientLocation = 0x00; } break; case I2C_CLIENT_TRANSFER_EVENT_STOP_BIT_RECEIVED: //Stop Communication clientLocation = 0x00; break; case I2C_CLIENT_TRANSFER_EVENT_ERROR: //Error Event Handler clientLocation = 0x00; i2c_client_error_t errorState = I2C1_Client.ErrorGet(); if(errorState == I2C_CLIENT_ERROR_BUS_COLLISION) { // Bus Collision Error Handling } else if(errorState == I2C_CLIENT_ERROR_WRITE_COLLISION) { // Write Collision Error Handling } else if (errorState == I2C_CLIENT_ERROR_RECEIVE_OVERFLOW) { // Receive Overflow Error Handling } else if (errorState == I2C_CLIENT_ERROR_TRANSMIT_UNDERFLOW) { // Transmit Underflow Error Handling } else if (errorState == I2C_CLIENT_ERROR_READ_UNDERFLOW) { // Read Underflow Error Handling } break; default: break; } return true; }
I2C Client Interrupt Example
This example assumes that the MCU is configured as a client and responds to the host commands to write or read data via the Client_Application switch case, which selects and implements the appropriate action based on the events that occur.
#define I2C_CLIENT_LOCATION_SIZE 10 //Private functions static bool Client_Application(i2c_client_transfer_event_t event); // Private variable volatile static uint8_t CLIENT_DATA[I2C_CLIENT_LOCATION_SIZE] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09 }; static uint8_t clientLocation = 0x00; static bool isClientLocation = false; int I2C_client_example_interrupt(void) { SYSTEM_Initialize(); INTERRUPT_GlobalInterruptEnable(); I2C1_Client.CallbackRegister(Client_Application); while (1) { } } static bool Client_Application(i2c_client_transfer_event_t event) { switch (event) { case I2C_CLIENT_TRANSFER_EVENT_ADDR_MATCH: //Address Match Event if (I2C1_Client.TransferDirGet() == I2C_CLIENT_TRANSFER_DIR_WRITE) { isClientLocation = true; } break; case I2C_CLIENT_TRANSFER_EVENT_RX_READY: //Read the data sent by I2C Host if (isClientLocation ) { clientLocation = I2C1_Client.ReadByte(); isClientLocation = false; break; } else { CLIENT_DATA[clientLocation ++] = I2C1_Client.ReadByte(); if (clientLocation >= I2C_CLIENT_LOCATION_SIZE) { clientLocation = 0x00; } } break; case I2C_CLIENT_TRANSFER_EVENT_TX_READY: //Provide the Client data requested by the I2C Host I2C1_Client.WriteByte(CLIENT_DATA[clientLocation ++]); if (clientLocation >= I2C_CLIENT_LOCATION_SIZE) { clientLocation = 0x00; } break; case I2C_CLIENT_TRANSFER_EVENT_STOP_BIT_RECEIVED: //Stop Communication clientLocation = 0x00; break; case I2C_CLIENT_TRANSFER_EVENT_ERROR: //Error Event Handler clientLocation = 0x00; i2c_client_error_t errorState = I2C1_Client.ErrorGet(); if(errorState == I2C_CLIENT_ERROR_BUS_COLLISION) { // Bus Collision Error Handling } else if(errorState == I2C_CLIENT_ERROR_WRITE_COLLISION) { // Write Collision Error Handling } else if (errorState == I2C_CLIENT_ERROR_RECEIVE_OVERFLOW) { // Receive Overflow Error Handling } else if (errorState == I2C_CLIENT_ERROR_TRANSMIT_UNDERFLOW) { // Transmit Underflow Error Handling } else if (errorState == I2C_CLIENT_ERROR_READ_UNDERFLOW) { // Read Underflow Error Handling } break; default: break; } return true; }
2.4.4.2 Class Documentation
2.4.4.2.1 I2C_CLIENT_INTERFACE Struct Reference
The documentation for this struct was generated from the following file:
source/
Public Attributes
-
void(* Initialize )(void)
-
void(* Deinitialize )(void)
-
void(* WriteByte )(uint8_t wrByte)
-
uint8_t(* ReadByte )(void)
-
i2c_client_error_t(* ErrorGet )(void)
-
i2c_client_transfer_dir_t(* TransferDirGet )(void)
-
i2c_client_ack_status_t(* LastByteAckStatusGet )(void)
-
void(* CallbackRegister )(bool(*handler)(i2c_client_transfer_event_t clientEvent))
-
void(* Tasks )(void)
2.4.4.2.2 i2c_client_interface_t Struct Reference
Structure containing the function pointers of I2C driver.
Detailed Description
Structure containing the function pointers of I2C driver.
Section: Included FilesSection: Data Type Definitions
#include <i2c_client_interface.h>
The documentation for this struct was generated from the following file:
source/
2.4.4.3 File Documentation
2.4.4.3.1 source/i2c_client_interface.h File Reference
#include <stdbool.h> #include <stdint.h> #include "i2c_client_types.h"
Data structures
-
struct I2C_CLIENT_INTERFACE
Detailed Description
I2C Generated Driver Interface Header File
2.4.4.3.2 source/i2c_client_types.h File Reference
Enumerations
-
enum i2c_client_transfer_dir_t { I2C_CLIENT_TRANSFER_DIR_WRITE = 0, I2C_CLIENT_TRANSFER_DIR_READ = 1 }
I2C_CLIENT_TRANSFER_DIR Enumeration.
-
enum i2c_client_ack_status_t { I2C_CLIENT_ACK_STATUS_RECEIVED_ACK = 0, I2C_CLIENT_ACK_STATUS_RECEIVED_NACK = 1 }
I2C Ack/Nack status enumeration.
-
enum i2c_client_transfer_event_t { I2C_CLIENT_TRANSFER_EVENT_NONE = 0, I2C_CLIENT_TRANSFER_EVENT_ADDR_MATCH, I2C_CLIENT_TRANSFER_EVENT_RX_READY, I2C_CLIENT_TRANSFER_EVENT_TX_READY, I2C_CLIENT_TRANSFER_EVENT_STOP_BIT_RECEIVED, I2C_CLIENT_TRANSFER_EVENT_ERROR }
I2C notification event type.
-
enum i2c_client_error_t { I2C_CLIENT_ERROR_NONE = 0, I2C_CLIENT_ERROR_BUS_COLLISION, I2C_CLIENT_ERROR_WRITE_COLLISION, I2C_CLIENT_ERROR_RECEIVE_OVERFLOW, I2C_CLIENT_ERROR_TRANSMIT_UNDERFLOW, I2C_CLIENT_ERROR_READ_UNDERFLOW }
I2C client error type indicator.
Detailed Description
I2C Generated Driver Types Header File