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