ISF  2.1
Intelligent Sensing Framework for Kinetis with Processor Expert
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
fsl_i2c_master_driver.c
Go to the documentation of this file.
1 /*!
2 ********************************************************************************
3 * File: fsl_i2c_master_driver.c
4 *
5 * Copyright (c) 2014, Freescale Semiconductor, Inc.
6 *
7 *******************************************************************************/
8 /*!
9 * @file fsl_i2c_master_driver.c
10 * @brief \b fsl_i2c_master_driver.c implements i2c master driver layer.
11 */
12 #include "fsl_i2c_master_driver.h"
13 #include "isf_fsl_i2c_PEx.h"
14 #include "PE_Types.h"
15 #include "PE_Error.h"
16 #include "mqxlite.h"
17 #include "lwmem.h"
18 #include "isf_util.h"
19 /*******************************************************************************
20  * Definitions
21  ******************************************************************************/
22 
24 {
25  /*! The mask for a 7-bit I2C slave address.*/
27 };
28 extern uint8 gSys_NumI2cBuses;
30 static i2c_status_t i2c_master_driver_send_receive(i2c_master_t * master, const i2c_device_t * device,
31  i2c_direction_t direction, uint8 flag,
32  uint32_t subaddress,size_t subaddressLength,
33  uint8_t * data, size_t dataLength,
34  uint32_t timeout_ms);
35 #define I2C_WRITE_BUFF_SIZE_MAX 0x32
36 /*******************************************************************************
37  * Variables
38  ******************************************************************************/
39 
40 
41 /*******************************************************************************
42  * Code
43  ******************************************************************************/
44 
45  /***********************************************************************
46  *
47  * Function Name : i2c_master_init
48  * Description : initializes the I2C master mode driver.
49  * This function will initialize the I2C master mode driver, enable I2C clock,
50  * and enable I2C interrupt.
51  *
52  ***************************************************************************/
53 void i2c_master_init(uint32_t instance, i2c_master_t * master)
54 {
55 
56  if((master == NULL) || (instance >= gSys_NumI2cBuses)){
57  return ;
58  }
59  _mem_zero(master, sizeof(i2c_master_t));
60  master->instance = instance;
61  _lwevent_create(&master->i2cEventHandler, LWEVENT_AUTO_CLEAR);
62  master->pDeviceHandle = i2c_instance_tbl[instance].fnI2CLLDInit(master);
63 }
64 
65 /***********************************************************************
66  *
67  * Function Name : i2c_master_shutdown
68  * Description : shut down the I2C master mode driver.
69  * This function will shut down the I2C master mode driver, disable I2C clock,
70  * and disable I2C interrupt.
71  *
72  ***************************************************************************/
74 {
75  if((master == NULL) || (master->instance >= gSys_NumI2cBuses)){
76  return ;
77  }
78  i2c_instance_tbl[master->instance].fnI2CLLDDeint(master->pUserData);
79 }
80 
81 /***********************************************************************
82  *
83  * Function Name : i2c_master_configure_bus
84  * Description : None.
85  *
86  ***************************************************************************/
88 {
89  return kStatus_I2C_Success;
90 }
91 
92 /***********************************************************************
93  *
94  * Function Name : i2c_master_transfer
95  * Description : performs a blocking read or write transaction on the I2C bus.
96  * This function will configure bus for the specified devices, send the device
97  * address with r/w direction. If we have a subaddress, then that is always done
98  * as a write transfer prior to transferring the actual data. At the last, perform
99  * the main transfer.
100  *
101  ***************************************************************************/
103  const i2c_device_t * device,
104  i2c_direction_t direction,
105  bool flag,
106  uint32_t subaddress,
107  size_t subaddressLength,
108  uint8_t * data,
109  size_t dataLength,
110  size_t * actualLengthTransferred,
111  uint32_t timeout_ms)
112 {
113 
114  if((master == NULL) || (device == NULL) || (data == NULL)
115  || (master->instance >= gSys_NumI2cBuses)){
117  }
118  // call configuration( master, device);
119  // select the appropriate slave.
120  if(ERR_OK != i2c_instance_tbl[master->instance].fnI2CLLDDeviceSelect(master->pDeviceHandle, device->addrType, device->address)){
121  return kStatus_I2C_Fail;
122  }
123  return i2c_master_driver_send_receive(master, device, direction, flag, subaddress, subaddressLength, data, dataLength, timeout_ms );
124 }
125 /***********************************************************************
126  *
127  * Function Name : i2c_master_driver_send_receive
128  * Description : Generic low level read and write i2c data.
129  *
130  ***************************************************************************/
131 static i2c_status_t i2c_master_driver_send_receive(i2c_master_t * master, const i2c_device_t * device,
132  i2c_direction_t direction, uint8 flag,
133  uint32_t subaddress,size_t subaddressLength,
134  uint8_t * data, size_t dataLength,
135  uint32_t timeout_ms)
136 {
137  _mqx_uint event = 0;
138  // Set the read pointer to a memory address from which the read can be performed.
139  if(direction == kI2CRead){
140  if(subaddressLength){
141  if(ERR_OK != i2c_instance_tbl[master->instance].fnI2CLLDWrite(master->pDeviceHandle, &subaddress, subaddressLength, flag)){
142  return kStatus_I2C_Fail;
143  }
144  // wait for the transfer to complete.
145  event = _lwevent_wait_ticks(&master->i2cEventHandler, I2C_PEX_WRITE_EVENT_SUCCESS | I2C_PEX_WRITE_EVENT_ERROR,
146  FALSE, timeout_ms);
147  if((_lwevent_get_signalled() & I2C_PEX_WRITE_EVENT_ERROR) || (LWEVENT_WAIT_TIMEOUT == event)){
148  return kStatus_I2C_Fail;
149  }
150  }
151  flag = LDD_I2C_SEND_STOP; //@todo handling the flag settings properly.
152  if(ERR_OK != i2c_instance_tbl[master->instance].fnI2CLLDRead(master->pDeviceHandle, data, dataLength, flag)) {
153  return kStatus_I2C_Fail;
154  }
155 
156  // wait for the transfer to complete.
157  event = _lwevent_wait_ticks(&master->i2cEventHandler, I2C_PEX_WRITE_EVENT_SUCCESS | I2C_PEX_WRITE_EVENT_ERROR
159  if((_lwevent_get_signalled() & I2C_PEX_WRITE_EVENT_ERROR) || (_lwevent_get_signalled() & I2C_PEX_READ_EVENT_ERROR)
160  || (LWEVENT_WAIT_TIMEOUT == event)){
161  return kStatus_I2C_Fail;
162  }
163  }else{
164  if(dataLength > I2C_WRITE_BUFF_SIZE_MAX){
165  return kStatus_I2C_Fail;
166  }
168  // Concatenate the sub address and data.
169  buffer[0] = (uint8)subaddress;
170  isf_mem_copy(data, &buffer[1], dataLength);
171  if(ERR_OK != i2c_instance_tbl[master->instance].fnI2CLLDWrite(master->pDeviceHandle, &buffer, dataLength + 1, LDD_I2C_SEND_STOP)){
172  return kStatus_I2C_Fail;
173  }
174  // wait for the transfer to complete.
175  event = _lwevent_wait_ticks(&master->i2cEventHandler, I2C_PEX_WRITE_EVENT_SUCCESS | I2C_PEX_WRITE_EVENT_ERROR,
176  FALSE, timeout_ms);
177  if((_lwevent_get_signalled() & I2C_PEX_WRITE_EVENT_ERROR) || (LWEVENT_WAIT_TIMEOUT == event)){
178  return kStatus_I2C_Fail;
179  }
180  }
181  return kStatus_I2C_Success;
182 
183 }
184 
185 /*******************************************************************************
186  * EOF
187  ******************************************************************************/
188 
unsigned char uint8
This defines uint8 as unsigned char.
Definition: isf_types.h:18
This structure contains i2c LLD function pointers.
enum I2CDirection i2c_direction_t
Constants for the direction of an I2C transfer.
fsl_i2c_master_driver.h defines structures and types for the i2c master driver.
LWEVENT_STRUCT i2cEventHandler
#define I2C_PEX_WRITE_EVENT_SUCCESS
#define I2C_PEX_WRITE_EVENT_ERROR
uint8 gSys_NumI2cBuses
fnI2CDeint_t fnI2CLLDDeint
Information necessary to communicate with an I2C slave device.
#define FALSE
Definition: isf_types.h:56
void i2c_master_shutdown(i2c_master_t *master)
Shut down the driver.
fnI2CWrite_t fnI2CLLDWrite
i2c_status_t i2c_master_configure_bus(i2c_master_t *master, const i2c_device_t *device)
Configure the I2C bus to access a device.
fnI2CInit_t fnI2CLLDInit
The isf_util.h file contains the utility method declarations and macros.
void isf_mem_copy(void *src, void *dest, uint32 size)
memory copy
Definition: isf_util.c:99
Internal driver state information.
enum _i2c_status i2c_status_t
I2C status return codes.
#define I2C_PEX_READ_EVENT_SUCCESS
#define I2C_PEX_READ_EVENT_ERROR
i2c_instance_PEx i2c_instance_tbl[]
Lookup table for the LLD instance.
_i2c_master_constants
void i2c_master_init(uint32_t instance, i2c_master_t *master)
Initialize the I2C master mode driver.
LDD_I2C_TAddrType addrType
i2c_status_t i2c_master_transfer(i2c_master_t *master, const i2c_device_t *device, i2c_direction_t direction, bool flag, uint32_t subaddress, size_t subaddressLength, uint8_t *data, size_t dataLength, size_t *actualLengthTransferred, uint32_t timeout_ms)
Perform a blocking read or write transaction on the I2C bus.
LDD_TDeviceData * pDeviceHandle
LDD_TUserData * pUserData
fnI2CDeviceSelect_t fnI2CLLDDeviceSelect
#define I2C_WRITE_BUFF_SIZE_MAX
fnI2CRead_t fnI2CLLDRead