| LPCOpen Platform v1.03 LPCOpen Platform for NXP LPC Microcontrollers

- Main Page
- Modules
- Data Structures
- Files
- Related Pages

- File List
- Globals

All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
i2c.c
Go to the documentation of this file.
1 /*
2 * @brief I2C example
3 *
4 * @note
5 * Copyright(C) NXP Semiconductors, 2012
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 #include "board.h"
33
61 /*****************************************************************************
62 * Private types/enumerations/variables
63 ****************************************************************************/
64
66 #define I2C_MASTER_MODE 1
67
68 #define I2C_SLAVE_ADDR_7BIT (0x90)
69
70 #define I2C_SLAVE_ADDR_10BIT (0x2CA)
71
72 #define I2C_ROM_MEM_SIZE (0x100UL)
73
74 #define I2C_BITRATE (1000000)
75
76 #define BUFFER_SIZE (0xFF)
77
78 static I2C_HANDLE_T *i2c_handle;
79 static uint32_t i2cmem[I2C_ROM_MEM_SIZE];
80 volatile uint32_t error_code;
81 I2C_PARAM_T param;
82 I2C_RESULT_T result;
83 volatile bool isTxCompleted = false;
84 volatile bool isRxCompleted = false;
85 volatile bool isTxRxCompleted = false;
86
87 uint8_t Buffer[BUFFER_SIZE];
88 uint8_t TmpBuffer[BUFFER_SIZE];
89
90 /*****************************************************************************
91 * Public types/enumerations/variables
92 ****************************************************************************/
93
94 /*****************************************************************************
95 * Private functions
96 ****************************************************************************/
97
98 /* Initialize buffer */
99 static void Buffer_Init(uint8_t *buffer, uint32_t buf_len, uint8_t type)
100 {
101 uint8_t i;
102
103 if (type) {
104 for (i = 0; i < buf_len; i++) {
105 buffer[i] = i;
106 }
107 }
108 else {
109 for (i = 0; i < buf_len; i++) {
110 buffer[i] = 0;
111 }
112 }
113 }
114
115 /* If error occurs, turn LED 0 (red LED) on and wait forever */
116 static void spin_on_error(void)
117 {
118 while (1) {
119 /* Show the red LED continuously due to error */
120 Board_LED_Toggle(0);
121 }
122 }
123
124 /* Compare two buffers from position StartPos to StopPos */
125 static void Buffer_Compare(uint8_t *buffer1, uint8_t *buffer2, uint32_t StartPos, uint32_t StopPos)
126 {
127 uint32_t i = 0;
128 for (i = StartPos; i < StopPos; i++) {
129 if (buffer1[i] != buffer2[i]) {
130 /* buffer1 differs from buffer2 and red LED is shown due to error */
131 spin_on_error();
132 }
133 }
134 }
135
136 /* I2C Receive Callback function */
137 static void App_I2C_Callback_Receive(uint32_t err_code, uint32_t n)
138 {
139 isRxCompleted = true;
140 error_code = err_code;
141 }
142
143 /* I2C Transmit Callback function */
144 static void App_I2C_Callback_Transmit(uint32_t err_code, uint32_t n)
145 {
146 isTxCompleted = true;
147 error_code = err_code;
148 }
149 #if I2C_MASTER_MODE
150 /* I2C Transmit and Receive Callback function */
151 static void App_I2C_Callback_MasterTxRx(uint32_t err_code, uint32_t n)
152 {
153 isTxRxCompleted = true;
154 error_code = err_code;
155 }
156 #endif
157
158 #if I2C_MASTER_MODE
159 /* Master Polling Mode */
160 static void App_I2C_Master_Polling(void)
161 {
162 /* Transmit TmpBuffer */
163 /* Initialize buffer */
164 Buffer_Init(TmpBuffer, BUFFER_SIZE, 1);
165 TmpBuffer[0] = I2C_SLAVE_ADDR_7BIT;
166
167 param.num_bytes_send = BUFFER_SIZE;
168 param.buffer_ptr_send = &TmpBuffer[0];
169 param.stop_flag = 1;
170 do {
171 error_code = LPC_I2CD_API->i2c_master_transmit_poll(i2c_handle, &param, &result);
172 } while (error_code);
173
174 /* Receive Buffer and compare with TmpBuffer */
175 /* Initialize buffer */
176 Buffer_Init(Buffer, BUFFER_SIZE, 0);
177 Buffer[0] = I2C_SLAVE_ADDR_7BIT | 0x01;
178
179 param.num_bytes_recv = BUFFER_SIZE;
180 param.buffer_ptr_recv = &Buffer[0];
181 param.stop_flag = 1;
182 do {
183 error_code = LPC_I2CD_API->i2c_master_receive_poll(i2c_handle, &param, &result);
184 } while (error_code);
185
186 /* Verify */
187 Buffer_Compare(TmpBuffer, Buffer, 1, BUFFER_SIZE);
188
189 /* Transmit TmpBuffer and receive Buffer, then compare them together */
190 /* Initialize buffer */
191 Buffer_Init(Buffer, BUFFER_SIZE, 0);
192 Buffer[0] = I2C_SLAVE_ADDR_7BIT | 0x01;
193
194 TmpBuffer[0] = I2C_SLAVE_ADDR_7BIT;
195 TmpBuffer[1] = 0xBA;
196
197 param.num_bytes_send = BUFFER_SIZE;
198 param.buffer_ptr_send = &TmpBuffer[0];
199 param.num_bytes_recv = BUFFER_SIZE;
200 param.buffer_ptr_recv = &Buffer[0];
201 param.stop_flag = 1;
202
203 do {
204 error_code = LPC_I2CD_API->i2c_master_tx_rx_poll(i2c_handle, &param, &result);
205 } while (error_code);
206
207 /* Verify */
208 Buffer_Compare(TmpBuffer, Buffer, 1, BUFFER_SIZE);
209 }
210
211 /* Master Interrupt Mode */
212 static void App_I2C_Master_Interrupt(void)
213 {
214 /* Transmit TmpBuffer */
215 /* Initialize buffer */
216 Buffer_Init(TmpBuffer, BUFFER_SIZE, 1);
217 TmpBuffer[0] = I2C_SLAVE_ADDR_7BIT;
218
219 param.num_bytes_send = BUFFER_SIZE;
220 param.buffer_ptr_send = &TmpBuffer[0];
221 param.func_pt = App_I2C_Callback_Transmit;
222 param.stop_flag = 1;
223
224 NVIC_DisableIRQ(I2C_IRQn);
225 NVIC_ClearPendingIRQ(I2C_IRQn);
226 NVIC_EnableIRQ(I2C_IRQn);
227
228 do {
229 isTxCompleted = false;
230 LPC_I2CD_API->i2c_master_transmit_intr(i2c_handle, &param, &result);
231 while (!isTxCompleted) {}
232 } while (error_code);
233
234 /* Receive Buffer and compare with TmpBuffer */
235 /* Initialize buffer */
236 Buffer_Init(Buffer, BUFFER_SIZE, 0);
237 Buffer[0] = I2C_SLAVE_ADDR_7BIT | 0x01;
238
239 param.num_bytes_recv = BUFFER_SIZE;
240 param.buffer_ptr_recv = &Buffer[0];
241 param.func_pt = App_I2C_Callback_Receive;
242 param.stop_flag = 1;
243
244 do {
245 isRxCompleted = false;
246 LPC_I2CD_API->i2c_master_receive_intr(i2c_handle, &param, &result);
247 while (!isRxCompleted) {}
248 } while (error_code);
249
250 /* Verify */
251 Buffer_Compare(TmpBuffer, Buffer, 1, BUFFER_SIZE);
252
253 /* Transmit TmpBuffer and receive Buffer, then compare them together */
254 /* Initialize buffer */
255 Buffer_Init(Buffer, BUFFER_SIZE, 0);
256 Buffer[0] = I2C_SLAVE_ADDR_7BIT | 0x01;
257
258 TmpBuffer[0] = I2C_SLAVE_ADDR_7BIT;
259 TmpBuffer[1] = 0xBA;
260
261 param.num_bytes_send = BUFFER_SIZE;
262 param.buffer_ptr_send = &TmpBuffer[0];
263 param.num_bytes_recv = BUFFER_SIZE;
264 param.buffer_ptr_recv = &Buffer[0];
265 param.func_pt = App_I2C_Callback_MasterTxRx;
266 param.stop_flag = 1;
267
268 do {
269 isTxRxCompleted = false;
270 LPC_I2CD_API->i2c_master_tx_rx_intr(i2c_handle, &param, &result);
271 while (!isTxRxCompleted) {}
272 } while (error_code);
273
274 /* Verify */
275 Buffer_Compare(TmpBuffer, Buffer, 1, BUFFER_SIZE);
276 }
277
278 /* Master Mode with 10-bit address */
279 static void App_I2C_Master_10bitAddressTest(void)
280 {
281 /* Transmit Buffer to slave with 10-bit addressing mode */
282 /* Initialize buffer */
283 Buffer_Init(&TmpBuffer[1], (BUFFER_SIZE - 1), 1);
284 Buffer_Init(Buffer, BUFFER_SIZE, 0);
285
286 TmpBuffer[0] = ((I2C_SLAVE_ADDR_10BIT >> 7) & 0x06) | 0xF0; /* 4 MSBs of slave address in first byte of transmit buffer */
287 TmpBuffer[1] = I2C_SLAVE_ADDR_10BIT & 0x0FF;
288
289 param.num_bytes_send = BUFFER_SIZE;
290 param.buffer_ptr_send = &TmpBuffer[0];
291 param.func_pt = App_I2C_Callback_Transmit;
292
293 NVIC_DisableIRQ(I2C_IRQn);
294 NVIC_ClearPendingIRQ(I2C_IRQn);
295 NVIC_EnableIRQ(I2C_IRQn);
296
297 do {
298 isTxCompleted = false;
299 LPC_I2CD_API->i2c_master_transmit_intr(i2c_handle, &param, &result);
300 while (!isTxCompleted) {}
301 } while (error_code);
302
303 /* Receive buffer from slave with 10-bit addressing mode */
304 Buffer[0] = ((I2C_SLAVE_ADDR_10BIT >> 7) & 0x06) | 0xF0;
305
306 param.num_bytes_send = 2;
307 param.buffer_ptr_send = &TmpBuffer[0];
308 param.num_bytes_recv = BUFFER_SIZE;
309 param.buffer_ptr_recv = &Buffer[0];
310 param.func_pt = App_I2C_Callback_MasterTxRx;
311
312 NVIC_DisableIRQ(I2C_IRQn);
313 NVIC_ClearPendingIRQ(I2C_IRQn);
314 NVIC_EnableIRQ(I2C_IRQn);
315
316 do {
317 isTxRxCompleted = false;
318 LPC_I2CD_API->i2c_master_tx_rx_intr(i2c_handle, &param, &result);
319 while (!isTxRxCompleted) {}
320 } while (error_code);
321
322 /* Verify */
323 Buffer_Compare(TmpBuffer, Buffer, 0, BUFFER_SIZE);
324 }
325
326 #else
327 /* Slave Polling Mode */
328 static void App_I2C_Slave_Polling(void)
329 {
330 /* Receive an array of bytes from master */
331 /* Initialize buffer */
332 Buffer_Init(Buffer, BUFFER_SIZE, 0);
333 Buffer_Init(TmpBuffer, BUFFER_SIZE, 1);
334
335 param.num_bytes_recv = BUFFER_SIZE;
336 param.buffer_ptr_recv = &Buffer[0];
337 param.stop_flag = 1;
338 do {
339 error_code = LPC_I2CD_API->i2c_slave_receive_poll(i2c_handle, &param, &result);
340 } while (error_code);
341
342 /* Verify */
343 Buffer_Compare(TmpBuffer, Buffer, 1, BUFFER_SIZE);
344
345 /* Transmit the buffer received */
346 param.num_bytes_send = BUFFER_SIZE - 1;
347 param.buffer_ptr_send = &Buffer[1];
348 param.stop_flag = 1;
349 do {
350 error_code = LPC_I2CD_API->i2c_slave_transmit_poll(i2c_handle, &param, &result);
351 } while (error_code);
352
353 /* Receive an array of byte from master; if Buffer[1] is equal to 0xBA, send the received buffer to master */
354 /* Initialize buffer */
355 Buffer_Init(Buffer, BUFFER_SIZE, 0);
356
357 param.num_bytes_recv = BUFFER_SIZE;
358 param.buffer_ptr_recv = &Buffer[0];
359 param.stop_flag = 1;
360 do {
361 error_code = LPC_I2CD_API->i2c_slave_receive_poll(i2c_handle, &param, &result);
362 } while (error_code);
363
364 if (Buffer[1] == 0xBA) {
365 param.num_bytes_send = BUFFER_SIZE - 1;
366 param.buffer_ptr_send = &Buffer[1];
367 param.stop_flag = 1;
368 do {
369 error_code = LPC_I2CD_API->i2c_slave_transmit_poll(i2c_handle, &param, &result);
370 } while (error_code);
371 }
372 }
373
374 /* Slave Interrupt Mode */
375 static void App_I2C_Slave_Interrupt(void)
376 {
377 /* Receive an array of bytes from master */
378 /* Initialize buffer */
379 Buffer_Init(Buffer, BUFFER_SIZE, 0);
380 Buffer_Init(TmpBuffer, BUFFER_SIZE, 1);
381
382 param.num_bytes_recv = BUFFER_SIZE;
383 param.buffer_ptr_recv = &Buffer[0];
384 param.func_pt = App_I2C_Callback_Receive;
385 param.stop_flag = 1;
386
387 NVIC_DisableIRQ(I2C_IRQn);
388 NVIC_ClearPendingIRQ(I2C_IRQn);
389 NVIC_EnableIRQ(I2C_IRQn);
390
391 do {
392 isRxCompleted = false;
393 LPC_I2CD_API->i2c_slave_receive_intr(i2c_handle, &param, &result);
394 while (!isRxCompleted) {}
395 } while (error_code);
396
397 /* Verify */
398 Buffer_Compare(TmpBuffer, Buffer, 1, BUFFER_SIZE);
399
400 /* Transmit the buffer received */
401 param.num_bytes_send = BUFFER_SIZE - 1;
402 param.buffer_ptr_send = &TmpBuffer[1];
403 param.func_pt = App_I2C_Callback_Transmit;
404 param.stop_flag = 1;
405
406 do {
407 isTxCompleted = false;
408 LPC_I2CD_API->i2c_slave_transmit_intr(i2c_handle, &param, &result);
409 while (!isTxCompleted) {}
410 } while (error_code);
411
412 /* Receive an array of byte from master; if Buffer[1] is equal to 0xBA, send the received buffer to master */
413 /* Initialize buffer */
414 Buffer_Init(Buffer, BUFFER_SIZE, 0);
415
416 param.num_bytes_recv = BUFFER_SIZE;
417 param.buffer_ptr_recv = &Buffer[0];
418 param.func_pt = App_I2C_Callback_Receive;
419 param.stop_flag = 1;
420
421 do {
422 isRxCompleted = false;
423 LPC_I2CD_API->i2c_slave_receive_intr(i2c_handle, &param, &result);
424 while (!isRxCompleted) {}
425 } while (error_code);
426
427 if (Buffer[1] == 0xBA) {
428 param.num_bytes_send = BUFFER_SIZE - 1;
429 param.buffer_ptr_send = &Buffer[1];
430 param.func_pt = App_I2C_Callback_Transmit;
431 param.stop_flag = 1;
432
433 do {
434 isTxCompleted = false;
435 LPC_I2CD_API->i2c_slave_transmit_intr(i2c_handle, &param, &result);
436 while (!isTxCompleted) {}
437 } while (error_code);
438 }
439 }
440
441 /* Slave Mode with 10-bit address */
442 static void App_I2C_Slave_10bitAddressTest(void)
443 {
444 /* Receive buffer from master */
445 /* Initialize buffer */
446 Buffer_Init(Buffer, BUFFER_SIZE, 0);
447
448 param.num_bytes_recv = BUFFER_SIZE;
449 param.buffer_ptr_recv = &Buffer[0];
450 param.func_pt = App_I2C_Callback_Receive;
451 param.stop_flag = 1;
452
453 NVIC_DisableIRQ(I2C_IRQn);
454 NVIC_ClearPendingIRQ(I2C_IRQn);
455 NVIC_EnableIRQ(I2C_IRQn);
456
457 do {
458 isRxCompleted = false;
459 LPC_I2CD_API->i2c_slave_receive_intr(i2c_handle, &param, &result);
460 while (!isRxCompleted) {}
461 } while (error_code);
462
463 /* Send received buffer back to master */
464 param.num_bytes_send = BUFFER_SIZE - 1; /* Only send data + 1 byte slave address(only LSB 8bits) */
465 param.buffer_ptr_send = &Buffer[1];
466 param.func_pt = App_I2C_Callback_Transmit;
467 param.stop_flag = 1;
468
469 do {
470 isTxCompleted = false;
471 LPC_I2CD_API->i2c_slave_transmit_intr(i2c_handle, &param, &result);
472 while (!isTxCompleted) {}
473 } while (error_code);
474 }
475
476 #endif
477
478 /*****************************************************************************
479 * Public functions
480 ****************************************************************************/
481
486 void I2C_IRQHandler(void)
487 {
488 // Board_LED_Toggle(1);
489 LPC_I2CD_API->i2c_isr_handler(i2c_handle);
490 }
491
496 void HW_Setup(void)
497 {
498 volatile uint32_t mem;
499
500 /* Generic Initialization */
501 Board_Init();
502 Board_I2C_Init();
503 Chip_I2C_Init();
504
505 /* Get the I2C memory size needed */
506 mem = LPC_I2CD_API->i2c_get_mem_size();
507
508 /* Perform a sanity check on the storage allocation */
509 if (I2C_ROM_MEM_SIZE < (mem / sizeof(uint32_t))) {
510 spin_on_error();
511 }
512
513 /* Setup the I2C */
514 i2c_handle = LPC_I2CD_API->i2c_setup(LPC_I2C_BASE, i2cmem);
515
516 /* Check the API return value for a valid handle */
517 if (i2c_handle != NULL) {
518 /* initialize the I2C with the configuration parameters */
519 error_code = LPC_I2CD_API->i2c_set_bitrate(i2c_handle, Chip_Clock_GetSystemClockRate(), I2C_BITRATE);
520 if (error_code) {
521 spin_on_error();
522 }
523 }
524 }
525
530 int main(void) {
531 HW_Setup();
532
533 Board_LED_Set(0, false);
534 Board_LED_Set(1, false);
535
536 #if I2C_MASTER_MODE
537 App_I2C_Master_Polling();
538 App_I2C_Master_Interrupt();
539 App_I2C_Master_10bitAddressTest();
540
541 #else
542 error_code =
543 LPC_I2CD_API->i2c_set_slave_addr(i2c_handle,
544 ((I2C_SLAVE_ADDR_7BIT << 8) | (((I2C_SLAVE_ADDR_10BIT >> 7) & 0x06) | 0xF0)),
545 (0 | ((I2C_SLAVE_ADDR_10BIT & 0x0FF) << 8) ));
546 if (error_code) {
547 spin_on_error();
548 }
549
550 App_I2C_Slave_Polling();
551 App_I2C_Slave_Interrupt();
552 App_I2C_Slave_10bitAddressTest();
553
554 #endif
555 /* Show the blue LED if no errors occurs */
556 Board_LED_Set(1, true);
557
558 while (1) {
559 __WFE();
560 }
561 return 0;
562 }
563