2.3 I2C Client Driver
2.3.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 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.3.2 Required Header Files:
For Client 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_client/i2c_client_interface.h"
2.3.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 with each of them:
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, which selects and implements 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, which selects and implements the appropriate action based on the events that occur.
2.3.4 Module Documentation
2.3.4.1 TWI_CLIENT_DRIVER
2.3.4.1.1 Module description
Modules
-
This header file provides APIs for the TWI1 driver.
TWI_CLIENT_INTERFACE
This header file provides APIs for the TWI1 driver.
Module description
This header file provides APIs for the TWI1 driver.
Data structures
-
struct i2c_client_interface_t
Structure containing the function pointers of I2C driver.
TWI_CLIENT_TYPES
This header file provides APIs for the TWI1 driver.
Module description
This header file provides APIs for the TWI1 driver.
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_ERROR, I2C_CLIENT_ERROR_COLLISION }
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_ERROR |
I2C Bus Error occurred | |
I2C_CLIENT_ERROR_COLLISION |
I2C Collision 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.3.4.2 I2C_client_example
2.3.4.2.1 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
2.3.4.2.2 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"
2.3.4.2.3 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; }
2.3.4.2.4 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.3.5 Class Documentation
2.3.5.1 I2C_CLIENT_INTERFACE Struct Reference
The documentation for this struct was generated from the following file:
source/
2.3.5.1.1 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.3.5.2 i2c_client_interface_t Struct Reference
Structure containing the function pointers of I2C driver.
2.3.5.2.1 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.3.6 File Documentation
2.3.6.1 source/i2c_client_interface.h File Reference
#include <stdbool.h> #include <stdint.h> #include "i2c_client_types.h"
2.3.6.1.1 Data structures
-
struct I2C_CLIENT_INTERFACE
2.3.6.1.2 Detailed Description
TWI1 Generated Driver API Header File
2.3.6.2 source/i2c_client_types.h File Reference
2.3.6.2.1 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_ERROR, I2C_CLIENT_ERROR_COLLISION }
I2C client error type indicator.
2.3.6.2.2 Detailed Description
TWI1 Generated Driver API Header File