1 /*
2  * @brief LPC15xx I2C driver
3  *
4  * @note
5  * Copyright(C) NXP Semiconductors, 2014
6  * All rights reserved.
7  *
8  * @par
9  * Software that is described herein is for illustrative purposes only
10  * which provides customers with programming information regarding the
11  * LPC products.  This software is supplied "AS IS" without any warranties of
12  * any kind, and NXP Semiconductors and its licensor disclaim any and
13  * all warranties, express or implied, including all implied warranties of
14  * merchantability, fitness for a particular purpose and non-infringement of
15  * intellectual property rights.  NXP Semiconductors assumes no responsibility
16  * or liability for the use of the software, conveys no license or rights under any
17  * patent, copyright, mask work right, or any other intellectual property rights in
18  * or to any products. NXP Semiconductors reserves the right to make changes
19  * in the software without notification. NXP Semiconductors also makes no
20  * representation or warranty that such application will be suitable for the
21  * specified use without further testing or modification.
22  *
23  * @par
24  * Permission to use, copy, modify, and distribute this software and its
25  * documentation is hereby granted, under NXP Semiconductors' and its
26  * licensor's relevant copyrights in the software, without fee, provided that it
27  * is used in conjunction with NXP Semiconductors microcontrollers.  This
28  * copyright, permission, and disclaimer notice must appear in all copies of
29  * this code.
30  */
31 
32 #ifndef __I2CM_15XX_H_
33 #define __I2CM_15XX_H_
34 
35 #include "i2c_common_15xx.h"
36 
37 #ifdef __cplusplus
38 extern "C" {
39 #endif
40 
41 /** @defgroup I2CM_15XX CHIP: LPC15xx I2C master-only driver
42  * @ingroup I2C_15XX
43  * This driver only works in master mode. To describe the I2C transactions
44  * following symbols are used in driver documentation.
45  *
46  * Key to symbols
47  * ==============
48  * S     (1 bit) : Start bit
49  * P     (1 bit) : Stop bit
50  * Rd/Wr (1 bit) : Read/Write bit. Rd equals 1, Wr equals 0.
51  * A, NA (1 bit) : Acknowledge and Not-Acknowledge bit.
52  * Addr  (7 bits): I2C 7 bit address. Note that this can be expanded as usual to
53  *                 get a 10 bit I2C address.
54  * Data  (8 bits): A plain data byte. Sometimes, I write DataLow, DataHigh
55  *                 for 16 bit data.
56  * [..]: Data sent by I2C device, as opposed to data sent by the host adapter.
57  * @{
58  */
59 
60 /** I2CM_15XX_STATUS_TYPES I2C master transfer status types
61  * @{
62  */
63 
64 #define I2CM_STATUS_OK              0x00		/*!< Requested Request was executed successfully. */
65 #define I2CM_STATUS_ERROR           0x01		/*!< Unknown error condition. */
66 #define I2CM_STATUS_NAK_ADR         0x02		/*!< No acknowledgement received from slave during address phase. */
67 #define I2CM_STATUS_BUS_ERROR       0x03		/*!< I2C bus error */
68 #define I2CM_STATUS_NAK_DAT           0x04		/*!< No acknowledgement received from slave during address phase. */
69 #define I2CM_STATUS_ARBLOST         0x05		/*!< Arbitration lost. */
70 #define I2CM_STATUS_BUSY            0xFF		/*!< I2C transmistter is busy. */
71 
72 /**
73  * @}
74  */
75 
76 /**
77  * @brief Master transfer data structure definitions
78  */
79 typedef struct {
80 	const uint8_t *txBuff;	/*!< Pointer to array of bytes to be transmitted */
81 	uint8_t *rxBuff;				/*!< Pointer memory where bytes received from I2C be stored */
82 	uint16_t txSz;					/*!< Number of bytes in transmit array,
83 									                if 0 only receive transfer will be carried on */
84 	uint16_t rxSz;					/*!< Number of bytes to received,
85 									                if 0 only transmission we be carried on */
86 	uint16_t status;				/*!< Status of the current I2C transfer */
87 	uint8_t slaveAddr;			/*!< 7-bit I2C Slave address */
88 } I2CM_XFER_T;
89 
90 /**
91  * @brief	Sets HIGH and LOW duty cycle registers
92  * @param	pI2C	: Pointer to selected I2C peripheral
93  * @param	sclH	: Number of I2C_PCLK cycles for the SCL HIGH time value between (2 - 9).
94  * @param	sclL	: Number of I2C_PCLK cycles for the SCL LOW time value between (2 - 9).
95  * @return	Nothing
96  * @note	The I2C clock divider should be set to the appropriate value before calling this function
97  *				The I2C baud is determined by the following formula: <br>
98  *        I2C_bitFrequency = (I2C_PCLK)/(I2C_CLKDIV * (sclH + sclL)) <br>
99  *				where I2C_PCLK is the frequency of the System clock and I2C_CLKDIV is I2C clock divider
100  */
Chip_I2CM_SetDutyCycle(LPC_I2C_T * pI2C,uint16_t sclH,uint16_t sclL)101 static INLINE void Chip_I2CM_SetDutyCycle(LPC_I2C_T *pI2C, uint16_t sclH, uint16_t sclL)
102 {
103 	pI2C->MSTTIME = (((sclH - 2) & 0x07) << 4) | ((sclL - 2) & 0x07);
104 }
105 
106 /**
107  * @brief	Set up bus speed for LPC_I2C controller
108  * @param	pI2C		: Pointer to selected I2C peripheral
109  * @param	busSpeed	: I2C bus clock rate
110  * @return	Nothing
111  * @note	Per I2C specification the busSpeed should be
112  *          @li 100000 for Standard mode
113  *          @li 400000 for Fast mode
114  *          @li 1000000 for Fast mode plus
115  *          IOCON registers corresponding to I2C pads should be updated
116  *          according to the bus mode.
117  */
118 void Chip_I2CM_SetBusSpeed(LPC_I2C_T *pI2C, uint32_t busSpeed);
119 
120 /**
121  * @brief	Enable I2C Master interface
122  * @param	pI2C	: Pointer to selected I2C peripheral
123  * @return	Nothing
124  * @note
125  */
Chip_I2CM_Enable(LPC_I2C_T * pI2C)126 static INLINE void Chip_I2CM_Enable(LPC_I2C_T *pI2C)
127 {
128 	pI2C->CFG = (pI2C->CFG & I2C_CFG_MASK) | I2C_CFG_MSTEN;
129 }
130 
131 /**
132  * @brief	Disable I2C Master interface
133  * @param	pI2C	: Pointer to selected I2C peripheral
134  * @return	Nothing
135  * @note
136  */
Chip_I2CM_Disable(LPC_I2C_T * pI2C)137 static INLINE void Chip_I2CM_Disable(LPC_I2C_T *pI2C)
138 {
139 	pI2C->CFG = (pI2C->CFG & I2C_CFG_MASK) & ~I2C_CFG_MSTEN;
140 }
141 
142 /**
143  * @brief	Get I2C Status
144  * @param	pI2C	: Pointer to selected I2C peripheral
145  * @return	I2C Status register value
146  * @note	This function returns the value of the status register.
147  */
Chip_I2CM_GetStatus(LPC_I2C_T * pI2C)148 static INLINE uint32_t Chip_I2CM_GetStatus(LPC_I2C_T *pI2C)
149 {
150 	return pI2C->STAT;
151 }
152 
153 /**
154  * @brief	Clear I2C status bits (master)
155  * @param	pI2C	: Pointer to selected I2C peripheral
156  * @param clrStatus : Status bit to clear, ORed Value of I2C_STAT_MSTRARBLOSS and I2C_STAT_MSTSTSTPERR
157  * @return	Nothing
158  * @note	This function clears selected status flags.
159  */
Chip_I2CM_ClearStatus(LPC_I2C_T * pI2C,uint32_t clrStatus)160 static INLINE void Chip_I2CM_ClearStatus(LPC_I2C_T *pI2C, uint32_t clrStatus)
161 {
162 	/* Clear Master Arbitration Loss and Start, Stop Error */
163 	pI2C->STAT = clrStatus & (I2C_STAT_MSTRARBLOSS | I2C_STAT_MSTSTSTPERR);
164 }
165 
166 /**
167  * @brief	Check if I2C Master is pending
168  * @param	pI2C	: Pointer to selected I2C peripheral
169  * @return	Returns TRUE if the Master is pending else returns FALSE
170  * @note
171  */
Chip_I2CM_IsMasterPending(LPC_I2C_T * pI2C)172 static INLINE bool Chip_I2CM_IsMasterPending(LPC_I2C_T *pI2C)
173 {
174 	return (pI2C->STAT & I2C_STAT_MSTPENDING) != 0;
175 }
176 
177 /**
178  * @brief	Get current state of the I2C Master
179  * @param	pI2C	: Pointer to selected I2C peripheral
180  * @return	Master State Code, a value in the range of 0 - 4
181  * @note	After the Master is pending this state code tells the reason
182  *        for Master pending.
183  */
Chip_I2CM_GetMasterState(LPC_I2C_T * pI2C)184 static INLINE uint32_t Chip_I2CM_GetMasterState(LPC_I2C_T *pI2C)
185 {
186 	return (pI2C->STAT & I2C_STAT_MSTSTATE) >> 1;
187 }
188 
189 /**
190  * @brief	Transmit START or Repeat-START signal on I2C bus
191  * @param	pI2C	: Pointer to selected I2C peripheral
192  * @return	Nothing
193  * @note	This function sets the controller to transmit START condition when
194  *        the bus becomes free. This should be called only when master is pending.
195  *				The function writes a complete value to Master Control register, ORing is not advised.
196  */
Chip_I2CM_SendStart(LPC_I2C_T * pI2C)197 static INLINE void Chip_I2CM_SendStart(LPC_I2C_T *pI2C)
198 {
199 	pI2C->MSTCTL = I2C_MSTCTL_MSTSTART;
200 }
201 
202 /**
203  * @brief	Transmit STOP signal on I2C bus
204  * @param	pI2C	: Pointer to selected I2C peripheral
205  * @return	Nothing
206  * @note	This function sets the controller to transmit STOP condition.
207  *				This should be called only when master is pending. The function writes a
208  *				complete value to Master Control register, ORing is not advised.
209  */
Chip_I2CM_SendStop(LPC_I2C_T * pI2C)210 static INLINE void Chip_I2CM_SendStop(LPC_I2C_T *pI2C)
211 {
212 	pI2C->MSTCTL = I2C_MSTCTL_MSTSTOP;
213 }
214 
215 /**
216  * @brief	Master Continue transfer operation
217  * @param	pI2C	: Pointer to selected I2C peripheral
218  * @return	Nothing
219  * @note	This function sets the master controller to continue transmission.
220  *				This should be called only when master is pending. The function writes a
221  *				complete value to Master Control register, ORing is not advised.
222  */
Chip_I2CM_MasterContinue(LPC_I2C_T * pI2C)223 static INLINE void Chip_I2CM_MasterContinue(LPC_I2C_T *pI2C)
224 {
225 	pI2C->MSTCTL = I2C_MSTCTL_MSTCONTINUE;
226 }
227 
228 /**
229  * @brief	Transmit a single data byte through the I2C peripheral (master)
230  * @param	pI2C	: Pointer to selected I2C peripheral
231  * @param	data	: Byte to transmit
232  * @return	Nothing
233  * @note	This function attempts to place a byte into the I2C Master
234  *			Data Register
235  *
236  */
Chip_I2CM_WriteByte(LPC_I2C_T * pI2C,uint8_t data)237 static INLINE void Chip_I2CM_WriteByte(LPC_I2C_T *pI2C, uint8_t data)
238 {
239 	pI2C->MSTDAT = (uint32_t) data;
240 }
241 
242 /**
243  * @brief	Read a single byte data from the I2C peripheral (master)
244  * @param	pI2C	: Pointer to selected I2C peripheral
245  * @return	A single byte of data read
246  * @note	This function reads a byte from the I2C receive hold register
247  *			regardless of I2C state.
248  */
Chip_I2CM_ReadByte(LPC_I2C_T * pI2C)249 static INLINE uint8_t Chip_I2CM_ReadByte(LPC_I2C_T *pI2C)
250 {
251 	return (uint8_t) (pI2C->MSTDAT & I2C_MSTDAT_DATAMASK);
252 }
253 
254 /**
255  * @brief	Transfer state change handler
256  * @param	pI2C	: Pointer to selected I2C peripheral
257  * @param	xfer	: Pointer to a I2CM_XFER_T structure see notes below
258  * @return Returns non-zero value on completion of transfer. The @a status
259  *         member of @a xfer structure contains the current status of the
260  *         transfer at the end of the call.
261  * @note
262  * The parameter @a xfer should be same as the one passed to Chip_I2CM_Xfer()
263  * routine. This function should be called from the I2C interrupt handler
264  * only when a master interrupt occurs.
265  */
266 uint32_t Chip_I2CM_XferHandler(LPC_I2C_T *pI2C, I2CM_XFER_T *xfer);
267 
268 /**
269  * @brief	Transmit and Receive data in master mode
270  * @param	pI2C	: Pointer to selected I2C peripheral
271  * @param	xfer	: Pointer to a I2CM_XFER_T structure see notes below
272  * @return	Nothing
273  * @note
274  * The parameter @a xfer should have its member @a slaveAddr initialized
275  * to the 7-Bit slave address to which the master will do the xfer, Bit0
276  * to bit6 should have the address and Bit8 is ignored. During the transfer
277  * no code (like event handler) must change the content of the memory
278  * pointed to by @a xfer. The member of @a xfer, @a txBuff and @a txSz be
279  * initialized to the memory from which the I2C must pick the data to be
280  * transfered to slave and the number of bytes to send respectively, similarly
281  * @a rxBuff and @a rxSz must have pointer to memroy where data received
282  * from slave be stored and the number of data to get from slave respectilvely.
283  * Following types of transfers are possible:
284  * - Write-only transfer: When @a rxSz member of @a xfer is set to 0.
285  *
286  *          S Addr Wr [A] txBuff0 [A] txBuff1 [A] ... txBuffN [A] P
287  *
288  *      - If I2CM_XFER_OPTION_IGNORE_NACK is set in @a options memeber
289  *
290  *          S Addr Wr [A] txBuff0 [A or NA] ... txBuffN [A or NA] P
291  *
292  * - Read-only transfer: When @a txSz member of @a xfer is set to 0.
293  *
294  *          S Addr Rd [A] [rxBuff0] A [rxBuff1] A ... [rxBuffN] NA P
295  *
296  *      - If I2CM_XFER_OPTION_LAST_RX_ACK is set in @a options memeber
297  *
298  *          S Addr Rd [A] [rxBuff0] A [rxBuff1] A ... [rxBuffN] A P
299  *
300  * - Read-Write transfer: When @a rxSz and @ txSz members of @a xfer are non-zero.
301  *
302  *          S Addr Wr [A] txBuff0 [A] txBuff1 [A] ... txBuffN [A]
303  *              S Addr Rd [A] [rxBuff0] A [rxBuff1] A ... [rxBuffN] NA P
304  *
305  */
306 void Chip_I2CM_Xfer(LPC_I2C_T *pI2C, I2CM_XFER_T *xfer);
307 
308 /**
309  * @brief	Transmit and Receive data in master mode
310  * @param	pI2C	: Pointer to selected I2C peripheral
311  * @param	xfer	: Pointer to a I2CM_XFER_T structure see notes below
312  * @return Returns non-zero value on succesful completion of transfer.
313  * @note
314  * This function operates same as Chip_I2CM_Xfer(), but is a blocking call.
315  */
316 uint32_t Chip_I2CM_XferBlocking(LPC_I2C_T *pI2C, I2CM_XFER_T *xfer);
317 
318 /**
319  * @}
320  */
321 
322  #ifdef __cplusplus
323 }
324 #endif
325 
326 #endif /* __I2C_15XX_H_ */
327